使用std :: ifstream和getc读取换行符的区别

时间:2018-05-11 23:02:40

标签: c++

如果我使用此文件读取文件:

std::string readfile(const std::string &filename)
{
    std::ifstream t(filename);
    std::string str;
    str.assign(std::istreambuf_iterator<char>(t),
               std::istreambuf_iterator<char>());
    return str;
}

我发现返回的字符串的换行符与文件的实际内容不同。该文件使用\r\n,而返回的字符串仅包含\n

我通过使用旧的c风格功能确认了这一点:

std::string readfile_c(const std::string &filename)
{
    FILE *f = fopen(filename.c_str(), "rb");
    std::string str;
    char c;
    while ((c = getc(f)) != EOF)
        str.push_back(c);
    fclose(f);
    return str;
}

尝试两者:

int main(int argc, char **argv)
{
    const std::string filename = "work\\actionlabel.html";
    std::string content1(readfile(filename));
    std::string content2(readfile_c(filename));
}

给了我这个:

debugger

如图所示,content1(来自 readfile )只有 \ n 换行符和content2(来自 readfile_c )具有文件的实际换行符 \ r \ n

为什么会有区别?

1 个答案:

答案 0 :(得分:1)

Streams默认为文本模式,其中文件的内容可能与流所看到的内容不匹配。例如,在Windows中,磁盘文件包含\r\n行结尾,但C ++文本流只会看到\n行结尾。此功能有助于编写必须处理不同操作系统约定的可移植代码。

二进制模式中,文件内容与文本内容完全匹配。

在代码fopen(filename.c_str(), "rb");中您指定了二进制模式,但在ifstream中您没有指定二进制模式;给你文字模式。

要在这两种情况下获得相同的行为,您可以"r"使用fopen,在两种情况下使用文本模式,或使用std::ios::binary作为ifstream的第二个参数,在两种情况下都给出二进制模式。