I’m trying to optimise the way I parse a big list of stats from a single string, by only iterating through the string once. This is fairly important since I’m changing stats quite regularly, and I need to be able to convert my struct to a string (and vice-versa) fairly often. It seems wasteful to use the normal method for parsing options from a string from the engine, since it requires parsing the whole string for each option.
The string is formatted initially pretty simple, it’s done in the same way options are given to a URL or command line:
So, the output of this is basically:
?1=#?2=#?3=# ... etc
Since I know the order of options in the string is always the same, I should be able to parse them fairly easily - but I’m having massive problems with line-ending characters being appended to strings when I make them. This is how I’m trying to parse the string:
TArray<FString, TInlineAllocator<PLAYERDATA_NUMITEMS>> IndividualOptions;
const FString EQUALS = TEXT("=");
const FString QUESTIONMARK = TEXT("?");
Iterates the 'String' Array, finds all options in sequential order or entry
Y'all better pray the incoming string is valid...
for (int32 StrIdx = 0; StrIdx < InDataString.Len(); StrIdx++)
{
if (&InDataString[StrIdx] == *EQUALS)
{
// Simple Error Checking
const int32 PrevIndex = StrIdx - 1;
const int32 NextIndex = StrIdx + 1;
// 1 - If the previous entry was a question mark, then we have an invalid option name
if (InDataString.IsValidIndex(PrevIndex) && &InDataString[PrevIndex] == *QUESTIONMARK)
{
UE_LOG(LogECGame, Warning, TEXT("Invalid Option Name for Option '%i'"), IndividualOptions.Num() + 1);
return false;
}
// 2 - If the next entry is a question mark, then we an invalid value
if (InDataString.IsValidIndex(NextIndex) && &InDataString[NextIndex] == *QUESTIONMARK)
{
UE_LOG(LogECGame, Warning, TEXT("Invalid Option Value for Option '%i'"), IndividualOptions.Num() + 1);
return false;
}
FString ThisOptionValue = TEXT("");
// Keep searching until we find the next '?' mark, or reach the end of the string
for (int32 SubStrIdx = StrIdx + 1; SubStrIdx < InDataString.Len(); SubStrIdx++)
{
// If we reach a question mark, that's the start of the next option
const FString SubChar = &InDataString[SubStrIdx];
if (SubChar == QUESTIONMARK) { break; }
ThisOptionValue += SubChar;
}
IndividualOptions.Add(ThisOptionValue);
}
}
// Ensure we have the correct number of options
if (IndividualOptions.Num() < PLAYERDATA_NUMITEMS)
{
UE_LOG(LogECGame, Warning, TEXT("Unable to parse all player data. Current: '%i' - Required: '%i'"), IndividualOptions.Num(), PLAYERDATA_NUMITEMS);
return false;
}
// Now we actually convert the strings to use-able data
PlayerLevel = FCString::Atoi(*IndividualOptions[0]);
PlayerXP = FCString::Atoi(*IndividualOptions[1]);
DarkCredits = FCString::Atoi(*IndividualOptions[2]);
LightCredits = FCString::Atoi(*IndividualOptions[3]);
Kills = FCString::Atoi(*IndividualOptions[4]);
Assists = FCString::Atoi(*IndividualOptions[5]);
Deaths = FCString::Atoi(*IndividualOptions[6]);
Suicides = FCString::Atoi(*IndividualOptions[7]);
return true;
The problem I’m having is that no options are ever parsed, because the ‘EQUALS’ FString is being converted to TChar with both ‘=’ and ‘/0’ (line-ending character I believe?) I think I’m messing up a few of the conversions between TCHAR and FString.
Does anybody have any insight on this?