使用带有多种类型的行尾字符的get line()

时间:2012-12-21 19:23:16

标签: c++ delimiter getline

我以下列方式使用std :: getline():

 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();

    }

问题是我在mac上编码(有些文件会被Windows工具和苹果工具修改)。某些行尾字符是\ r而不是\ n,因此我的文件字符串永远不会分成行。我相信还有第三个我应该检查的。我找不到为多个endOfLine字符设置delim参数的示例。

如果有人可以帮助这个例子,或者采用一种非常好的方法。 感谢

1 个答案:

答案 0 :(得分:2)

std::getline()仅支持一行结束符。在文本模式下打开文件时,系统的行结束序列将转换为单行结束符(\n)。但是,这不涉及来自其他系统的行尾字符序列。实际上,所有真正需要做的就是从剩下的输入中删除\r字符。删除字符的最佳方法可能是创建过滤流缓冲区。这是一个微不足道的,未经测试的,可能是缓慢的(它不是缓冲,这意味着每个角色都有虚函数调用;这是可怕的;创建缓冲版本并不困难):

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;
};

您可以将此过滤器与现有的流缓冲区一起使用,如下所示:

std::ifstream fin("foo");
normalizebuf  sbuf(fin.rdbuf());
std::istream  in(&sbuf);

...然后您使用in来删除所有\r个字符的文件。