int myint = 1;
float myfloat = 2.0f;
TChar* mystring = L"123";
FString::Printf(TEXT("%2d,%.3f,%s",myint,myfloat,mystring);
int myint = 0;
FString mystring = TEXT(“1”);
LexFromString(myint,*mystring);
float myfloat = 0;
FString mystring = TEXT(“1.0”);
LexFromString(myfloat ,*mystring);
float mybool = 0;
FString mystring = TEXT(“true”);
LexFromString(mybool ,*mystring);
FString 的数据是一个Tarray的列表,TCHAR一般是wchar
/** Array holding the character data */
typedef TArray DataType;
DataType Data;
这个Data的数据可以通过操作符获取
/**
* Get pointer to the string
*
* @Return Pointer to Array of TCHAR if Num, otherwise the empty string
/
FORCEINLINE const TCHAR operator() const
{
return Data.Num() ? Data.GetData() : TEXT("");
}
其中Data.GetData() 返回是TArray,数据存储的首地址。就可以把TArray当数组处理了。
/**
*Get string as array of TCHARS
*
* @warning: Operations on the TArray<*CHAR> can be unsafe, such as adding
* non-terminating 0’s or removing the terminating zero.
*/
FORCEINLINE DataType& GetCharArray()
{
return Data;
}
/**
* Create empty string of given size with zero terminating character
*
* @param Slack length of empty string to create
*/
FORCEINLINE void Empty( int32 Slack=0 )
{
Data.Empty(Slack);
}
/**
* Test whether this string is empty
*
* @return true if this string is empty, otherwise return false.
*/
FORCEINLINE bool IsEmpty() const
{
return Data.Num() <= 1;
}
这里不是num为0的时候是空的,最少有一个,就是字符串的结束符。
使用[]操作符可以访问data的指定位置的字符。
FORCEINLINE const TCHAR& operator[]( int32 Index ) const
{
checkf(IsValidIndex(Index), TEXT("String index out of bounds: Index %i from a string with a length of %i"), Index, Len());
return Data.GetData()[Index];
}
添加字符串使用append方法,其中Appendf可以按照格式追加,而不是追加指定的一个类型,最为方便
/**
* Just like Printf, but appends the formatted text to the existing FString instead.
* @return a reference to the modified string, so that it can be chained
*/
template
typename TEnableIf::Value, FString&>::Type Appendf(const FmtType& Fmt, Types... Args)
{
static_assert(TIsArrayOrRefOfType::Value, "Formatting string must be a TCHAR array.");
static_assert(TAnd...>::Value, "Invalid argument(s) passed to FString::Appendf");
AppendfImpl(*this, Fmt, Args...);
return *this;
}
* Searches the string for a character
*
* @param InChar the character to search for
* @param Index out the position the character was found at, INDEX_NONE if return is false
* @return true if character was found in this string, otherwise false
*/
FORCEINLINE bool FindChar( TCHAR InChar, int32& Index ) const
{
return Data.Find(InChar, Index);
}
/**
/**
* Searches the string for the last occurrence of a character
*
* @param InChar the character to search for
* @param Index out the position the character was found at, INDEX_NONE if return is false
* @return true if character was found in this string, otherwise false
*/
FORCEINLINE bool FindLastChar( TCHAR InChar, int32& Index ) const
{
return Data.FindLast(InChar, Index);
}
/**
* Searches the string for a substring, and returns index into this string
* of the first found instance. Can search from beginning or end, and ignore case or not.
*
* @param SubStr The string array of TCHAR to search for
* @param StartPosition The start character position to search from
* @param SearchCase Indicates whether the search is case sensitive or not
* @param SearchDir Indicates whether the search starts at the beginning or at the end.
*/
int32 Find( const TCHAR* SubStr, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase,
ESearchDir::Type SearchDir = ESearchDir::FromStart, int32 StartPosition=INDEX_NONE ) const;
/**
* Test whether this string starts with given string.
*
* @param SearchCase Indicates whether the search is case sensitive or not ( defaults to ESearchCase::IgnoreCase )
* @return true if this string begins with specified text, false otherwise
*/
bool StartsWith(const TCHAR* InSuffix, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase) const;
/**
* Test whether this string ends with given string.
*
* @param SearchCase Indicates whether the search is case sensitive or not ( defaults to ESearchCase::IgnoreCase )
* @return true if this string ends with specified text, false otherwise
*/
bool EndsWith(const TCHAR* InSuffix, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase) const;
/**
* Returns whether this string contains the specified substring.
*
* @param SubStr Find to search for
* @param SearchCase Indicates whether the search is case sensitive or not ( defaults to ESearchCase::IgnoreCase )
* @param SearchDir Indicates whether the search starts at the beginning or at the end ( defaults to ESearchDir::FromStart )
* @return Returns whether the string contains the substring
**/
FORCEINLINE bool Contains(const TCHAR* SubStr, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase,
ESearchDir::Type SearchDir = ESearchDir::FromStart ) const
{
return Find(SubStr, SearchCase, SearchDir) != INDEX_NONE;
}
/** Returns the left most given number of characters */
FORCEINLINE FString Left( int32 Count ) const &
{
return FString( FMath::Clamp(Count,0,Len()), **this );
}
FORCEINLINE FString Left(int32 Count) &&
{
LeftInline(Count, false);
return MoveTemp(*this);
}
/** Modifies the string such that it is now the left most given number of characters */
FORCEINLINE void LeftInline(int32 Count, bool bAllowShrinking = true)
{
const int32 Length = Len();
Count = FMath::Clamp(Count, 0, Length);
RemoveAt(Count, Length-Count, bAllowShrinking);
}
/** Returns the left most characters from the string chopping the given number of characters from the end */
FORCEINLINE FString LeftChop( int32 Count ) const &
{
const int32 Length = Len();
return FString( FMath::Clamp(Length-Count,0, Length), **this );
}
FORCEINLINE FString LeftChop(int32 Count)&&
{
LeftChopInline(Count, false);
return MoveTemp(*this);
}
/** Modifies the string such that it is now the left most characters chopping the given number of characters from the end */
FORCEINLINE void LeftChopInline(int32 Count, bool bAllowShrinking = true)
{
const int32 Length = Len();
RemoveAt(FMath::Clamp(Length-Count, 0, Length), Count, bAllowShrinking);
}
/** Returns the string to the right of the specified location, counting back from the right (end of the word). */
FORCEINLINE FString Right( int32 Count ) const &
{
const int32 Length = Len();
return FString( **this + Length-FMath::Clamp(Count,0,Length) );
}
FORCEINLINE FString Right(int32 Count) &&
{
RightInline(Count, false);
return MoveTemp(*this);
}
/** Modifies the string such that it is now the right most given number of characters */
FORCEINLINE void RightInline(int32 Count, bool bAllowShrinking = true)
{
const int32 Length = Len();
RemoveAt(0, Length-FMath::Clamp(Count,0,Length), bAllowShrinking);
}
/** Returns the string to the right of the specified location, counting forward from the left (from the beginning of the word). */
FORCEINLINE FString RightChop( int32 Count ) const &
{
const int32 Length = Len();
return FString( **this + Length-FMath::Clamp(Length-Count,0, Length) );
}
FORCEINLINE FString RightChop(int32 Count) &&
{
RightChopInline(Count, false);
return MoveTemp(*this);
}
/** Modifies the string such that it is now the string to the right of the specified location, counting forward from the left (from the beginning of the word). */
FORCEINLINE void RightChopInline(int32 Count, bool bAllowShrinking = true)
{
RemoveAt(0, Count, bAllowShrinking);
}
/** Returns the substring from Start position for Count characters. */
FORCEINLINE FString Mid( int32 Start, int32 Count=MAX_int32 ) const &
{
FString Result;
if (Count >= 0)
{
const int32 Length = Len();
const int32 RequestedStart = Start;
Start = FMath::Clamp(Start, 0, Length);
const int32 End = (int32)FMath::Clamp((int64)Count + RequestedStart, (int64)Start, (int64)Length);
Result = FString(End-Start, **this + Start);
}
return Result;
}
FORCEINLINE FString Mid(int32 Start, int32 Count = MAX_int32) &&
{
MidInline(Start, Count, false);
return MoveTemp(*this);
}
/** Modifies the string such that it is now the substring from Start position for Count characters. */
FORCEINLINE void MidInline(int32 Start, int32 Count = MAX_int32, bool bAllowShrinking = true)
{
LeftInline((int32)FMath::Min((int64)Count+Start, (int64)MAX_int32), false);
RightChopInline(Start, bAllowShrinking);
}
/**
/**
* Removes whitespace characters from the start of this string.
* @note Unlike Trim() this function returns a copy, and does not mutate the string.
*/
FString TrimStart() const &;
/**
* Removes whitespace characters from the end of this string.
* @note Unlike TrimTrailing() this function returns a copy, and does not mutate the string.
*/
FString TrimEnd() const &;
* Splits this string at given string position case sensitive.
*
* @param InStr The string to search and split at
* @param LeftS out the string to the left of InStr, not updated if return is false. LeftS must not point to the same location as RightS, but can point to this.
* @param RightS out the string to the right of InStr, not updated if return is false. RightS must not point to the same location as LeftS, but can point to this.
* @param SearchCase Indicates whether the search is case sensitive or not ( defaults to ESearchCase::IgnoreCase )
* @param SearchDir Indicates whether the search starts at the beginning or at the end ( defaults to ESearchDir::FromStart )
* @return true if string is split, otherwise false
*/
bool Split(const FString& InS, FString* LeftS, FString* RightS, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase,
ESearchDir::Type SearchDir = ESearchDir::FromStart) const
{
check(LeftS != RightS || LeftS == nullptr);
int32 InPos = Find(InS, SearchCase, SearchDir);
if (InPos < 0) { return false; }
if (LeftS)
{
if (LeftS != this)
{
*LeftS = Left(InPos);
if (RightS) { *RightS = Mid(InPos + InS.Len()); }
}
else
{
// we know that RightS can't be this so we can safely modify it before we deal with LeftS
if (RightS) { *RightS = Mid(InPos + InS.Len()); }
*LeftS = Left(InPos);
}
}
else if (RightS)
{
*RightS = Mid(InPos + InS.Len());
}
return true;
}
/**
* Removes whitespace characters from the start and end of this string. Modifies the string in-place.
*/
void TrimStartAndEndInline();
/**
* Removes whitespace characters from the start and end of this string.
* @note Unlike Trim() this function returns a copy, and does not mutate the string.
*/
FString TrimStartAndEnd() const &;
/**
* Replace all occurrences of a substring in this string
*
* @param From substring to replace
* @param To substring to replace From with
* @param SearchCase Indicates whether the search is case sensitive or not ( defaults to ESearchCase::IgnoreCase )
* @return a copy of this string with the replacement made
*/
FString Replace(const TCHAR* From, const TCHAR* To, ESearchCase::Type SearchCase = ESearchCase::IgnoreCase) const &;
/** Converts an integer to a string. */
static FORCEINLINE FString FromInt( int32 Num )
{
FString Ret;
Ret.AppendInt(Num);
return Ret;
}
/** appends the integer InNum to this string */
void AppendInt( int32 InNum );
// Takes the number passed in and formats the string in comma format ( 12345 becomes "12,345")
static FString FormatAsNumber( int32 InNumber );
/**
* Converts a string into a boolean value
* 1, "True", "Yes", FCoreTexts::True, FCoreTexts::Yes, and non-zero integers become true
* 0, "False", "No", FCoreTexts::False, FCoreTexts::No, and unparsable values become false
*
* @return The boolean value
*/
bool ToBool() const;
/**
//bool
FString MyFString = MyBool ?TEXT("true") :TEXT("false");
* Converts a float string with the trailing zeros stripped
* For example - 1.234 will be "1.234" rather than "1.234000"
*
* @param InFloat The float to sanitize
* @param InMinFractionalDigits The minimum number of fractional digits the number should have (will be padded with zero)
*
* @return sanitized string version of float
*/
static FString SanitizeFloat( double InFloat, const int32 InMinFractionalDigits = 1 );
/**
* Constructs FString object similarly to how classic sprintf works.
*
* @param Format Format string that specifies how FString should be built optionally using additional args. Refer to standard printf format.
* @param ... Depending on format function may require additional arguments to build output object.
*
* @returns FString object that was constructed using format and additional parameters.
*/
template
static typename TEnableIf::Value, FString>::Type Printf(const FmtType& Fmt, Types... Args)
{
static_assert(TIsArrayOrRefOfType::Value, "Formatting string must be a TCHAR array.");
static_assert(TAnd...>::Value, "Invalid argument(s) passed to FString::Printf");
return PrintfImpl(Fmt, Args...);
}
/** Covert a string buffer to intrinsic types */
inline void LexFromString(int8& OutValue, const TCHAR* Buffer) { OutValue = (int8)FCString::Atoi(Buffer); }
inline void LexFromString(int16& OutValue, const TCHAR* Buffer) { OutValue = (int16)FCString::Atoi(Buffer); }
inline void LexFromString(int32& OutValue, const TCHAR* Buffer) { OutValue = (int32)FCString::Atoi(Buffer); }
inline void LexFromString(int64& OutValue, const TCHAR* Buffer) { OutValue = FCString::Atoi64(Buffer); }
inline void LexFromString(uint8& OutValue, const TCHAR* Buffer) { OutValue = (uint8)FCString::Atoi(Buffer); }
inline void LexFromString(uint16& OutValue, const TCHAR* Buffer) { OutValue = (uint16)FCString::Atoi(Buffer); }
inline void LexFromString(uint32& OutValue, const TCHAR* Buffer) { OutValue = (uint32)FCString::Atoi64(Buffer); } //64 because this unsigned and so Atoi might overflow
inline void LexFromString(uint64& OutValue, const TCHAR* Buffer) { OutValue = FCString::Strtoui64(Buffer, nullptr, 0); }
inline void LexFromString(float& OutValue, const TCHAR* Buffer) { OutValue = FCString::Atof(Buffer); }
inline void LexFromString(double& OutValue, const TCHAR* Buffer) { OutValue = FCString::Atod(Buffer); }
inline void LexFromString(bool& OutValue, const TCHAR* Buffer) { OutValue = FCString::ToBool(Buffer); }
inline void LexFromString(FString& OutValue, const TCHAR* Buffer) { OutValue = Buffer;}
template
typename TEnableIf::Value, FString>::Type
LexToString(const CharType* Ptr)
{
return FString(Ptr);
}
inline FString LexToString(bool Value)
{
return Value ? TEXT("true") : TEXT("false");
}
FORCEINLINE FString LexToString(FString&& Str)
{
return MoveTemp(Str);
}
FORCEINLINE FString LexToString(const FString& Str)
{
return Str;
}
/** Helper template to convert to sanitized strings */
template
FString LexToSanitizedString(const T& Value)
{
return LexToString(Value);
}
从这里可以发现,其实最好的从其他的类型转FString的方法是使用Printf
最好的从FString转其他类型的方法是借用FCString,先将FString转为wchar的string然后再通过FCString的方法处理wchar*.
FString可以通过*操作转化为wchar*
std::string可以通过c_str转化为char*
FSTring和std::string转化的桥梁是char* 和Wchar*
UTF8_TO_TCHAR char* -> Wchar*
TCHAR_TO_UTF8 Wchar* -> char*
ANSI_TO_TCHAR char* -> Wchar*
TCHAR_TO_ANSI Wchar* -> char*
// Usage of these should be replaced with StringCasts.
#define TCHAR_TO_ANSI(str) (ANSICHAR*)StringCast(static_cast(str)).Get()
#define ANSI_TO_TCHAR(str) (TCHAR*)StringCast(static_cast(str)).Get()
#define TCHAR_TO_UTF8(str) (ANSICHAR*)FTCHARToUTF8((const TCHAR*)str).Get()
#define UTF8_TO_TCHAR(str) (TCHAR*)FUTF8ToTCHAR((const ANSICHAR*)str).Get()