[英]Difference in reading newlines using std::ifstream and getc
If I read in a file using this: 如果我使用此文件读入:
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;
}
I find that the returned string has newlines which differ from the file's actual content. 我发现返回的字符串中的换行符与文件的实际内容不同。 The file uses \\r\\n
, whereas the returned string only contains \\n
. 该文件使用\\r\\n
,而返回的字符串仅包含\\n
。
I confirmed this by using an old c-style function: 我通过使用旧的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;
}
Trying them both out: 都尝试一下:
int main(int argc, char **argv)
{
const std::string filename = "work\\actionlabel.html";
std::string content1(readfile(filename));
std::string content2(readfile_c(filename));
}
gives me this: 给我这个:
As shown, content1
(from readfile ) has only \\n newlines, and content2
(from readfile_c ) has the file's actual newlines \\r\\n . 如图所示, content1
(来自readfile )只有\\ n换行符, content2
(来自readfile_c )只有文件的实际换行符\\ r \\ n 。
Why is there a difference? 为什么有区别?
Streams default to text mode in which the content of the file may not match the content seen by the stream. 流默认为文本模式,在该模式下 ,文件内容可能与流看到的内容不匹配。 For example in Windows, a disk file contains \\r\\n
line endings but the C++ text stream will only see \\n
for the line endings. 例如,在Windows中,磁盘文件包含\\r\\n
行尾,但是C ++文本流将仅看到\\n
作为行尾。 This feature helps in writing portable code that has to deal with differing OS conventions. 此功能有助于编写必须处理不同OS约定的可移植代码。
In binary mode it is intended that the file content, exactly matches the content seen by the stream. 在二进制模式下 ,文件内容应与流中看到的内容完全匹配。
In the code fopen(filename.c_str(), "rb");
在代码fopen(filename.c_str(), "rb");
you specified binary mode, but in your ifstream
you did not; 您指定了二进制模式,但是在ifstream
中没有指定; giving you text mode. 给你文本模式。
To get the same behaviour in both cases you could either use "r"
for fopen
, giving text mode in both cases, or use std::ios::binary
as second argument to ifstream
, giving binary mode in both cases. 为了在两种情况下都具有相同的行为,您可以在fopen
使用"r"
,在两种情况下均使用文本模式,或者在std::ios::binary
作为ifstream
第二个参数,在两种情况下均采用二进制模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.