std::getline() reads carriage return \r into the string, how to avoid that?

The problem is that in Windows a newline is represented as CR + LF which is: "\r\n" and in Unix it is LF which is just "\n".
Your std::getline(...) command is reading till the "\n" in "leer\r\n" and discards the "\n", your resulting string will be:

"leer\r"

To solve this problem and convert files between Unix/Windows there are the 2 tools dos2unix and unix2dos. The Ubuntu equivalents are fromdos and todos, you will need fromdos to convert your Windows text file to a Unix text file.

To test wether a file uses CR + LF or LF you can do:

dos2unix < myfile.txt | cmp -s - myfile.txt

which was ansered here on the Unix & Linux StackExchange site.


And it seems like it saves "leer\\r" in the object instead of only "leer" but I tried to replace "leer\\r" as well and it still doesn`t work. I still cant understand why my if (obj.m_Sternbild == "leer\\r") didn`t work because imo it should have worked?

It should be:

if (obj.m_Sternbild == "leer\r")

without escaping the backslash \, because \r is read into the string.

Edit:

As @FreelanceConsultant in the comment below write: The above answer is not a general solution. Because a binary compiled either on Windows or Unix should work for text files for both platforms.

There are two solutions for that.

The obvious one is, to compare against two different versions of the input. With std::getline the Windows result is "leer\r" and Unix result is "leer".

if (obj.m_Sternbild == "leer\r" || obj.m_Sternbild == "leer")

Another solution would be to normalize the newline representation to one form and only check against that. It is a matter of taste and performance, because you would need to create new strings. See his answer as example.

Leave a Comment