Reading Text File Line by Line

I want to load Lines from a text file to an Array, i already tried it with FFileHelper::LoadANSITextFileToStrings
The Problem i got then was that it doesn’t show the Special Characters in the Text.
The Function LoadFileToString does show the Sepecial Characters, but then i just get 1 FString with the Complete Content from the Text File.

With LoadFileToString, the Special Characters are shown:

FString GameDir = FPaths::GameDir();
	FString CompleteFilePath = GameDir + "Content/Languages/" + language + ".txt";

	FString FileData = "";
	FFileHelper::LoadFileToString(FileData, *CompleteFilePath);
	UE_LOG(VisionRunnerLanguageManager, Log, TEXT("LangFile: \n %s"), *FileData);
	return  CompleteFilePath;

Does anyone know how to do this. With Special Characters i mean these “ÄÖÜß”, these are very common Characters in German.

Thanks.
Greetings
Cybergebi

1 Like

Very old topic but does FString::ParseIntoArray work for you?

TArray<FString> lines;
int32 lineCount = FileData.ParseIntoArray(&lines, _T("\n"), true);

I’m currently not at home. But thanks i will try it this weekend :slight_smile:

Thanks, it works :smiley:

But VS says that i should not use ParseIntoArray on to large files. I will see if it works later when my file gets bigger. I use it to Translate all the GUIs and Subtitles.

Why can’t you use standard C/C++ techniques (cin, FILE, stringstream, etc.)?

“Why can’t you use standard C/C++ techniques (cin, FILE, stringstream, etc.)?” you probably can but you can also stay within Unreal’s data structures.

Regarding the O^N allocation issue, I actually use this on some fairly large files and haven’t had to optimize yet. Looking at the implementation (below) it seems that if you presize the array it should become O(N).

	//Do a little counting up front to try and avoid n^2 reallocations when adding strings to the array.
	int iMaxLines = CountChar(*fileData, _T('\n'));
    TArray<FString> lines;
	lines.Reserve(iMaxLines);
	int32 lineCount = fileData.ParseIntoArray(lines, _T("\n"), true);

Implementation:

int32 FString::ParseIntoArray( TArray<FString>& OutArray, const TCHAR* pchDelim, bool InCullEmpty ) const
{
	// Make sure the delimit string is not null or empty
	check(pchDelim);
	OutArray.Empty();
	const TCHAR *Start = Data.GetData();
	int32 DelimLength = FCString::Strlen(pchDelim);
	if (Start && DelimLength)
	{
		while( const TCHAR *At = FCString::Strstr(Start,pchDelim) )
		{
			if (!InCullEmpty || At-Start)
			{
				new (OutArray) FString(At-Start,Start);
			}
			Start = At + DelimLength;
		}
		if (!InCullEmpty || *Start)
		{
			new(OutArray) FString(Start);
		}

	}
	return OutArray.Num();
}