UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
StandardPlatformString.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
8#include "Misc/Char.h"
9
10// IWYU pragma: begin_exports
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <wchar.h>
15// IWYU pragma: end_exports
16
17#if PLATFORM_USE_GENERIC_STRING_IMPLEMENTATION && !PLATFORM_TCHAR_IS_CHAR16
18
23{
27
28 template <typename CharType>
29 static inline CharType* Strupr(CharType* Dest, SIZE_T DestCount)
30 {
31 for (CharType* Char = Dest; *Char && DestCount > 0; Char++, DestCount--)
32 {
34 }
35 return Dest;
36 }
37
38public:
39
43 static inline WIDECHAR* Strcpy(WIDECHAR* Dest, const WIDECHAR* Src)
44 {
45// Skip suggestions about using wcscpy_s instead.
47 return wcscpy(Dest, Src);
49 }
50
51 // This version was deprecated because Strcpy taking a size field does not match the CRT strcpy, and on some platforms the size field was being ignored.
52 // If the memzeroing causes a performance problem, request a new function StrcpyTruncate.
53 UE_DEPRECATED(5.6, "Use Strncpy instead. Note that Strncpy has a behavior difference from Strcpy: it memzeroes the entire DestCount-sized buffer after the end of string.")
54 static inline WIDECHAR* Strcpy(WIDECHAR* Dest, SIZE_T DestCount, const WIDECHAR* Src)
55 {
56 // Skip suggestions about using wcscpy_s instead.
58 return wcscpy(Dest, Src);
60 }
61
62 static inline WIDECHAR* Strncpy(WIDECHAR* Dest, const WIDECHAR* Src, SIZE_T MaxLen)
63 {
64// Skip suggestions about using wcsncpy_s instead.
66 wcsncpy(Dest, Src, MaxLen-1);
68 Dest[MaxLen-1]=0;
69 return Dest;
70 }
71
72 static inline WIDECHAR* Strcat(WIDECHAR* Dest, const WIDECHAR* Src)
73 {
74// Skip suggestions about using wcscat_s instead.
76 return (WIDECHAR*)wcscat( Dest, Src );
78 }
79
80 // This version was deprecated because Strcat taking a size field does not match the CRT strcat, and on some platforms the size field was being ignored.
81 UE_DEPRECATED(5.6, "Use Strncat instead. !!NOTE THAT STRNCAT takes SrcLen rather than DestCount. You must call Strncat(Dest, Src, DestCount - Strlen(Dest) - 1).")
82 static inline WIDECHAR* Strcat(WIDECHAR* Dest, SIZE_T DestCount, const WIDECHAR* Src)
83 {
84 // Skip suggestions about using wcscat_s instead.
86 return (WIDECHAR*)wcscat(Dest, Src);
88 }
89
90 static inline WIDECHAR* Strncat(WIDECHAR* Dest, const WIDECHAR* Src, SIZE_T SrcLen)
91 {
92 if (!SrcLen || !*Src)
93 {
94 return Dest;
95 }
96 WIDECHAR* NewDest = Dest + Strlen(Dest);
98 do
99 {
100 *NewDest++ = *Src++;
102 } while (AppendedCount < SrcLen && *Src);
103 *NewDest = 0;
104 return Dest;
105 }
106
107 static UE_FORCEINLINE_HINT int32 Strcmp( const WIDECHAR* String1, const WIDECHAR* String2 )
108 {
109 return wcscmp(String1, String2);
110 }
111
113 {
114 return wcsncmp( String1, String2, Count );
115 }
116
117 static UE_FORCEINLINE_HINT int32 Strlen( const WIDECHAR* String )
118 {
119 return (int32)wcslen( String );
120 }
121
122 static UE_FORCEINLINE_HINT int32 Strnlen( const WIDECHAR* String, SIZE_T StringSize )
123 {
124 return (int32)wcsnlen_s( String, StringSize );
125 }
126
127 static UE_FORCEINLINE_HINT const WIDECHAR* Strstr( const WIDECHAR* String, const WIDECHAR* Find)
128 {
129 return wcsstr( String, Find );
130 }
131
132 static UE_FORCEINLINE_HINT const WIDECHAR* Strchr( const WIDECHAR* String, WIDECHAR C)
133 {
134 return wcschr( String, C );
135 }
136
137 static UE_FORCEINLINE_HINT const WIDECHAR* Strrchr( const WIDECHAR* String, WIDECHAR C)
138 {
139 return wcsrchr( String, C );
140 }
141
142 static UE_FORCEINLINE_HINT int32 Atoi(const WIDECHAR* String)
143 {
144 return (int32)wcstol( String, NULL, 10 );
145 }
146
147 static UE_FORCEINLINE_HINT int64 Atoi64(const WIDECHAR* String)
148 {
149 return wcstoll( String, NULL, 10 );
150 }
151
152 static UE_FORCEINLINE_HINT float Atof(const WIDECHAR* String)
153 {
154 return wcstof( String, NULL );
155 }
156
157 static UE_FORCEINLINE_HINT double Atod(const WIDECHAR* String)
158 {
159 return wcstod( String, NULL );
160 }
161
162 static UE_FORCEINLINE_HINT int32 Strtoi( const WIDECHAR* Start, WIDECHAR** End, int32 Base )
163 {
164 return (int32)wcstol( Start, End, Base );
165 }
166
167 static UE_FORCEINLINE_HINT int64 Strtoi64( const WIDECHAR* Start, WIDECHAR** End, int32 Base )
168 {
169 return wcstoll( Start, End, Base );
170 }
171
172 static UE_FORCEINLINE_HINT uint64 Strtoui64( const WIDECHAR* Start, WIDECHAR** End, int32 Base )
173 {
174 return wcstoull( Start, End, Base );
175 }
176
177 static inline WIDECHAR* Strtok(WIDECHAR* StrToken, const WIDECHAR* Delim, WIDECHAR** Context)
178 {
179// Skip suggestions about using wcstok_s instead.
181 return wcstok(StrToken, Delim, Context);
183 }
184
185#if PLATFORM_USE_SYSTEM_VSWPRINTF
186 static int32 GetVarArgs( WIDECHAR* Dest, SIZE_T DestSize, const WIDECHAR*& Fmt, va_list ArgPtr )
187 {
188#if PLATFORM_USE_LS_SPEC_FOR_WIDECHAR
189 // fix up the Fmt string, as fast as possible, without using an FString
190 const WIDECHAR* OldFormat = Fmt;
191 WIDECHAR* NewFormat = (WIDECHAR*)alloca((Strlen(Fmt) * 2 + 1) * sizeof(WIDECHAR));
192
193 int32 NewIndex = 0;
194
195 for (; *OldFormat != 0; NewIndex++, OldFormat++)
196 {
197 // fix up %s -> %ls and %c -> %lc
198 if (OldFormat[0] == LITERAL(WIDECHAR, '%'))
199 {
200 NewFormat[NewIndex++] = *OldFormat++;
201
202 if (*OldFormat == LITERAL(WIDECHAR, '%'))
203 {
204 NewFormat[NewIndex] = *OldFormat;
205 }
206 else
207 {
208 const WIDECHAR* NextChar = OldFormat;
209
210 while(*NextChar != 0 && !FChar::IsAlpha(*NextChar))
211 {
212 NewFormat[NewIndex++] = *NextChar;
213 ++NextChar;
214 };
215
216 if (*NextChar == LITERAL(WIDECHAR, 's') || *NextChar == LITERAL(WIDECHAR, 'c'))
217 {
218 NewFormat[NewIndex++] = LITERAL(WIDECHAR, 'l');
219 NewFormat[NewIndex] = *NextChar;
220 }
221 else if (*NextChar == LITERAL(WIDECHAR, 'S'))
222 {
223 NewFormat[NewIndex] = LITERAL(WIDECHAR, 's');
224 }
225 else
226 {
227 NewFormat[NewIndex] = *NextChar;
228 }
229
231 }
232 }
233 else
234 {
235 NewFormat[NewIndex] = *OldFormat;
236 }
237 }
238 NewFormat[NewIndex] = 0;
240#else
242#endif
243 return Result;
244 }
245#else // PLATFORM_USE_SYSTEM_VSWPRINTF
246 static CORE_API int32 GetVarArgs( WIDECHAR* Dest, SIZE_T DestSize, const WIDECHAR*& Fmt, va_list ArgPtr );
247#endif // PLATFORM_USE_SYSTEM_VSWPRINTF
248
252 static inline ANSICHAR* Strcpy(ANSICHAR* Dest, const ANSICHAR* Src)
253 {
254// Skip suggestions about using strcpy_s instead.
256 return strcpy( Dest, Src );
258 }
259
260 // This version was deprecated because Strcpy taking a size field does not match the CRT strcpy, and on some platforms the size field was being ignored.
261 // If the memzeroing causes a performance problem, request a new function StrcpyTruncate.
262 UE_DEPRECATED(5.6, "Use Strncpy instead. Note that Strncpy has a behavior difference from Strcpy: it memzeroes the entire DestCount-sized buffer after the end of string.")
263 static inline ANSICHAR* Strcpy(ANSICHAR* Dest, SIZE_T DestCount, const ANSICHAR* Src)
264 {
265 // Skip suggestions about using strcpy_s instead.
267 return strcpy(Dest, Src);
269 }
270
271 static inline ANSICHAR* Strncpy(ANSICHAR* Dest, const ANSICHAR* Src, SIZE_T MaxLen)
272 {
273// Skip suggestions about using strncpy_s instead.
274PRAGMA_DISABLE_DEPRECATION_WARNINGS
275 ::strncpy(Dest, Src, MaxLen);
277 Dest[MaxLen-1]=0;
278 return Dest;
279 }
280
281 static inline ANSICHAR* Strcat(ANSICHAR* Dest, const ANSICHAR* Src)
282 {
283// Skip suggestions about using strcat_s instead.
285 return strcat( Dest, Src );
287 }
288
289 // This version was deprecated because Strcat taking a size field does not match the CRT strcat, and on some platforms the size field was being ignored.
290 UE_DEPRECATED(5.6, "Use Strncat instead. !!NOTE THAT STRNCAT takes SrcLen rather than DestSize. You must call Strncat(Dest, Src, DestCount - Strlen(Dest) - 1).")
291 static inline ANSICHAR* Strcat(ANSICHAR* Dest, SIZE_T DestCount, const ANSICHAR* Src)
292 {
293// Skip suggestions about using strcat_s instead.
295 return strcat(Dest, Src);
297 }
298
299 static UE_FORCEINLINE_HINT ANSICHAR* Strncat(ANSICHAR* Dest, const ANSICHAR* Src, SIZE_T SrcLen)
300 {
301 return (ANSICHAR*)strncat(Dest, Src, SrcLen);
302 }
303
304 static UE_FORCEINLINE_HINT int32 Strcmp( const ANSICHAR* String1, const ANSICHAR* String2 )
305 {
306 return strcmp(String1, String2);
307 }
308
310 {
311 return strncmp( String1, String2, Count );
312 }
313
314 static UE_FORCEINLINE_HINT int32 Strlen( const ANSICHAR* String )
315 {
316 return (int32)strlen( String );
317 }
318
319 static UE_FORCEINLINE_HINT int32 Strnlen( const ANSICHAR* String, SIZE_T StringSize )
320 {
321 return (int32)strnlen_s( String, StringSize );
322 }
323
324 static UE_FORCEINLINE_HINT const ANSICHAR* Strstr( const ANSICHAR* String, const ANSICHAR* Find)
325 {
326 return strstr(String, Find);
327 }
328
329 static UE_FORCEINLINE_HINT const ANSICHAR* Strchr( const ANSICHAR* String, ANSICHAR C)
330 {
331 return strchr(String, C);
332 }
333
334 static UE_FORCEINLINE_HINT const ANSICHAR* Strrchr( const ANSICHAR* String, ANSICHAR C)
335 {
336 return strrchr(String, C);
337 }
338
339 static UE_FORCEINLINE_HINT int32 Atoi(const ANSICHAR* String)
340 {
341 return atoi( String );
342 }
343
344 static UE_FORCEINLINE_HINT int64 Atoi64(const ANSICHAR* String)
345 {
346 return strtoll( String, NULL, 10 );
347 }
348
349 static UE_FORCEINLINE_HINT float Atof(const ANSICHAR* String)
350 {
351 return (float)atof( String );
352 }
353
354 static UE_FORCEINLINE_HINT double Atod(const ANSICHAR* String)
355 {
356 return atof( String );
357 }
358
359 static UE_FORCEINLINE_HINT int32 Strtoi( const ANSICHAR* Start, ANSICHAR** End, int32 Base )
360 {
361 return (int32)strtol( Start, End, Base );
362 }
363
364 static UE_FORCEINLINE_HINT int64 Strtoi64( const ANSICHAR* Start, ANSICHAR** End, int32 Base )
365 {
366 return strtoll(Start, End, Base);
367 }
368
369 static UE_FORCEINLINE_HINT uint64 Strtoui64( const ANSICHAR* Start, ANSICHAR** End, int32 Base )
370 {
371 return strtoull(Start, End, Base);
372 }
373
374 static inline ANSICHAR* Strtok(ANSICHAR* StrToken, const ANSICHAR* Delim, ANSICHAR** Context)
375 {
376// Skip suggestions about using strtok_s instead.
378 return strtok(StrToken, Delim);
380 }
381
382 static int32 GetVarArgs( ANSICHAR* Dest, SIZE_T DestSize, const ANSICHAR*& Fmt, va_list ArgPtr )
383 {
385 return (Result != -1 && Result < (int32)DestSize) ? Result : -1;
386 }
387
391 static UE_FORCEINLINE_HINT UTF8CHAR* Strcpy(UTF8CHAR* Dest, const UTF8CHAR* Src)
392 {
393 return (UTF8CHAR*)Strcpy((ANSICHAR*)Dest, (const ANSICHAR*)Src);
394 }
395
396 // This version was deprecated because Strcpy taking a size field does not match the CRT strcpy, and on some platforms the size field was being ignored.
397 // If the memzeroing causes a performance problem, request a new function StrcpyTruncate.
398 UE_DEPRECATED(5.6, "Use Strncpy instead. Note that Strncpy has a behavior difference from Strcpy: it memzeroes the entire DestCount-sized buffer after the end of string.")
399 static inline UTF8CHAR* Strcpy(UTF8CHAR* Dest, SIZE_T DestCount, const UTF8CHAR* Src)
400 {
402 return (UTF8CHAR*)Strcpy((ANSICHAR*)Dest, DestCount, (const ANSICHAR*)Src);
404 }
405
406 static UE_FORCEINLINE_HINT UTF8CHAR* Strncpy(UTF8CHAR* Dest, const UTF8CHAR* Src, SIZE_T MaxLen)
407 {
408 return (UTF8CHAR*)Strncpy((ANSICHAR*)Dest, (const ANSICHAR*)Src, MaxLen);
409 }
410
411 static UE_FORCEINLINE_HINT UTF8CHAR* Strcat(UTF8CHAR* Dest, const UTF8CHAR* Src)
412 {
413 return (UTF8CHAR*)Strcat((ANSICHAR*)Dest, (const ANSICHAR*)Src);
414 }
415
416 // This version was deprecated because Strcat taking a size field does not match the CRT strcat, and on some platforms the size field was being ignored.
417 UE_DEPRECATED(5.6, "Use Strncat instead. !!NOTE THAT STRNCAT takes SrcLen rather than DestSize. You must call Strncat(Dest, Src, DestCount - Strlen(Dest) - 1).")
418 static inline UTF8CHAR* Strcat(UTF8CHAR* Dest, SIZE_T DestCount, const UTF8CHAR* Src)
419 {
421 return (UTF8CHAR*)Strcat((ANSICHAR*)Dest, DestCount, (const ANSICHAR*)Src);
423 }
424
425 static UE_FORCEINLINE_HINT UTF8CHAR* Strncat(UTF8CHAR* Dest, const UTF8CHAR* Src, SIZE_T SrcLen)
426 {
427 return (UTF8CHAR*)Strncat((ANSICHAR*)Dest, (const ANSICHAR*)Src, SrcLen);
428 }
429
430 static UE_FORCEINLINE_HINT int32 Strcmp(const UTF8CHAR* String1, const UTF8CHAR* String2)
431 {
432 return Strcmp((const ANSICHAR*)String1, (const ANSICHAR*)String2);
433 }
434
436 {
437 return Strncmp((const ANSICHAR*)String1, (const ANSICHAR*)String2, Count);
438 }
439
440 static UE_FORCEINLINE_HINT int32 Strlen(const UTF8CHAR* String)
441 {
442 return Strlen((const ANSICHAR*)String);
443 }
444
446 {
447 return Strnlen((const ANSICHAR*)String, StringSize);
448 }
449
450 static UE_FORCEINLINE_HINT const UTF8CHAR* Strstr(const UTF8CHAR* String, const UTF8CHAR* Find)
451 {
452 return (const UTF8CHAR*)Strstr((const ANSICHAR*)String, (const ANSICHAR*)Find);
453 }
454
455 static UE_FORCEINLINE_HINT const UTF8CHAR* Strchr(const UTF8CHAR* String, UTF8CHAR C)
456 {
457 return (const UTF8CHAR*)Strchr((const ANSICHAR*)String, (ANSICHAR)C);
458 }
459
460 static UE_FORCEINLINE_HINT const UTF8CHAR* Strrchr(const UTF8CHAR* String, UTF8CHAR C)
461 {
462 return (const UTF8CHAR*)Strrchr((const ANSICHAR*)String, (ANSICHAR)C);
463 }
464
465 static UE_FORCEINLINE_HINT int32 Atoi(const UTF8CHAR* String)
466 {
467 return Atoi((const ANSICHAR*)String);
468 }
469
470 static UE_FORCEINLINE_HINT int64 Atoi64(const UTF8CHAR* String)
471 {
472 return Atoi64((const ANSICHAR*)String);
473 }
474
475 static UE_FORCEINLINE_HINT float Atof(const UTF8CHAR* String)
476 {
477 return Atof((const ANSICHAR*)String);
478 }
479
480 static UE_FORCEINLINE_HINT double Atod(const UTF8CHAR* String)
481 {
482 return Atod((const ANSICHAR*)String);
483 }
484
485 static UE_FORCEINLINE_HINT int32 Strtoi(const UTF8CHAR* Start, UTF8CHAR** End, int32 Base)
486 {
487 return Strtoi((const ANSICHAR*)Start, (ANSICHAR**)End, Base);
488 }
489
490 static UE_FORCEINLINE_HINT int64 Strtoi64(const UTF8CHAR* Start, UTF8CHAR** End, int32 Base)
491 {
492 return Strtoi64((const ANSICHAR*)Start, (ANSICHAR**)End, Base);
493 }
494
495 static UE_FORCEINLINE_HINT uint64 Strtoui64(const UTF8CHAR* Start, UTF8CHAR** End, int32 Base)
496 {
497 return Strtoui64((const ANSICHAR*)Start, (ANSICHAR**)End, Base);
498 }
499
501 {
502 return (UTF8CHAR*)Strtok((ANSICHAR*)StrToken, (const ANSICHAR*)Delim, (ANSICHAR**)Context);
503 }
504
505 static UE_FORCEINLINE_HINT int32 GetVarArgs(UTF8CHAR* Dest, SIZE_T DestSize, const UTF8CHAR*& Fmt, va_list ArgPtr)
506 {
507 return GetVarArgs((ANSICHAR*)Dest, DestSize, *(const ANSICHAR**)&Fmt, ArgPtr);
508 }
509
514 static inline int32 Strlen( const UCS2CHAR* String )
515 {
516 int32 Result = 0;
517 while (*String++)
518 {
519 ++Result;
520 }
521
522 return Result;
523 }
524
525 static inline int32 Strnlen( const UCS2CHAR* String, SIZE_T StringSize )
526 {
527 int32 Result = 0;
528 while (StringSize-- > 0 && *String++)
529 {
530 ++Result;
531 }
532
533 return Result;
534 }
535};
536
537#endif
#define NULL
Definition oodle2base.h:134
int vswprintf(TCHAR *dst, int count, const TCHAR *fmt, va_list arg)
ENGINE_API void StringSize(const UFont *Font, int32 &XL, int32 &YL, FStringView Text)
Definition Canvas.cpp:1181
#define LITERAL(CharType, StringLiteral)
Definition Char.h:31
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::CHAR16 UCS2CHAR
A 16-bit character containing a UCS2 (Unicode, 16-bit, fixed-width) code unit, used for compatibility...
Definition Platform.h:1139
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::WIDECHAR WIDECHAR
A wide character. Normally a signed type.
Definition Platform.h:1133
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::UTF8CHAR UTF8CHAR
An 8-bit character containing a UTF8 (Unicode, 8-bit, variable-width) code unit.
Definition Platform.h:1137
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:12
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:8
@ Char
Character type.
UE_STRING_CLASS Result(Forward< LhsType >(Lhs), RhsLen)
Definition String.cpp.inl:732
static CORE_API int32 Stricmp(const ANSICHAR *String1, const ANSICHAR *String2)
Definition GenericPlatformStricmp.cpp:93
static CORE_API int32 Strnicmp(const ANSICHAR *String1, const ANSICHAR *String2, SIZE_T Count)
Definition GenericPlatformStricmp.cpp:107
Definition GenericPlatformString.h:61
static CORE_API int32 Strncmp(const ANSICHAR *String1, const ANSICHAR *String2, SIZE_T Count)
Definition GenericPlatformString.cpp:719
static bool IsAlpha(CharType Char)
Definition Char.h:135
static CharType ToUpper(CharType Char)
Definition Char.h:80