问题
I am using std::getline() in the following manner:
std::fstream verify;
verify.open(myURI.c_str());
std::string countingLine;
if(verify.is_open()){
std::getline(verify, countingLine);
std::istringstream iss(countingLine);
size_t pos;
// Check for the conventional myFile header.
pos = iss.str().find("Time,Group,Percent,Sign,Focus");
if(pos == std::string::npos){//its not there
headerChk = false;
this->setStatusMessage("Invalid header for myFile file");
return 0;
}
// loop that does more validation
iss.clear();
}
The problem is I'm coding on a mac (and some files get modified with both windows tools and apple tools). Some end of line characters are \r instead of \n, so my file string is never broken into lines. I believe there is also a third one I should be checking for. I'm having trouble finding an example of setting up the delim parameter for multiple endOfLine characters.
If someone could help with that example or a different approach that would be great. Thanks
回答1:
std::getline()
only supports one end of line character. When opening a file in text mode, the system's end of line sequences are converted into one single end of line character (\n
). However, this doesn't deal with end of line character sequences from other systems. Practically, all what really needs to be done is to remove the \r
character from the input which remains. The best way to remove characters is probably to create a filtering stream buffer. Here is a trivial, untested, and probably slow one (it isn't buffering which means there is virtual function call for each individual character; this is horrific; creating a buffered version isn't much harder, though):
class normalizebuf
: std::streambuf {
std::streambuf* sbuf_;
char buffer_[1];
public:
normalizebuf(std::streambuf* sbuf): sbuf_(sbuf) {}
int underflow() {
int c = this->sbuf_->sbumpc();
while (c == std::char_traits<char>::to_int_type('\r')) {
c = this->sbuf->sbumpc();
}
if (c != std::char_traits<char>::eof()) {
this->buffer_[0] = std::char_traits<char>::to_char_type(c);
this->setg(this->buffer_, this->buffer_, this->buffer_ + 1);
}
return c;
};
You'd use this filter with an existing stream buffer, something like this:
std::ifstream fin("foo");
normalizebuf sbuf(fin.rdbuf());
std::istream in(&sbuf);
... and then you'd use in
to read the file with all \r
characters removed.
来源:https://stackoverflow.com/questions/13995971/using-get-line-with-multiple-types-of-end-of-line-characters