Issues parsing options from a string by iterating each character only once?

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:

050bd23ddbe7a1ac2410ae58fe0e75682f8962eb.jpeg

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?

I think the problem is here: &InDataString[PrevIndex] == *QUESTIONMARK
You first take a pointer to a symbol at PrevIndex and then compare it to a poiner to first symbol in QUESTIONMARK.
Try this one: InDataString[PrevIndex] == **QUESTIONMARK
Or just use TCHAR instead of FString for QUESTIONMARK and EQUALS

I’ll give that a go, thanks. Converting back and forth between FString and TCHAR can be a bit confusing.

If you are talking about the part when you concatenate them together, then it will look the same. You can use + to add FStrings and TCHARs without any additional work