Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
516 views
in Technique[技术] by (71.8m points)

c++ - std::getline() reads carriage return into the string, how to avoid that?

I need to read all attributes from a tеxt file that looks like the following for one Stern (engl.: Star) object. I need to replace the string "leer" with "" but there can also be a valid string which shouldn't be replaced with "".

I.e for another Stern object there could be "leer" instead of "Sol" as well.

Problem:
The problem is it doesn't replace the "leer" with the "". 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.

This is one Stern in the text file that should be read:

0
Sol
0.000005
0.000000
0.000000
leer
1
0

And this is my operator >> to read it:

istream& operator>>(istream& is, Stern& obj)
{
    string dummy;
    is >> obj.m_ID;
    getline(is, dummy);
    getline(is, obj.m_Bez);

    if (obj.m_Bez == "leer")
        obj.m_Bez = "";

    is >> obj.m_xKoord >> obj.m_yKoord >> obj.m_zKoord;
    getline(is,dummy);
    getline(is,obj.m_Sternbild);

    if (obj.m_Sternbild == "leer")
        obj.m_Sternbild = "";

    is >> obj.m_Index >> obj.m_PrimID;

    return is;
}

Stern.h:

#ifndef STERN_H
#define STERN_H
#include <string>
#include <iostream>

using namespace std;

class Stern
{
public:
    Stern();
    // 2.a)
    //Stern(int m_ID, string m_Bez, float m_xKoord, float m_yKoord, float m_zKoord, string m_Sternbild, int m_Index, int m_PrimID); 
    virtual ~Stern();

    void print() const; // 1.b)
    friend ostream& operator<<(ostream& os, const Stern& obj); // 1.b)i.
    friend istream& operator>>(istream& is, Stern& obj);


private:
    int m_ID;
    string m_Bez;
    float m_xKoord;
    float m_yKoord;
    float m_zKoord;
    string m_Sternbild;
    int m_Index;
    int m_PrimID;
};

#endif /* STERN_H */
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

"leer
"

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
")

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...