istream :: seekg与ios_base :: end可靠吗?

时间:2014-05-31 15:50:38

标签: c++ c++11 file-io io

考虑我用这种方式创建了一个文件:

std::ofstream osf("MyTextFile.txt");
string buffer="spam\neggs\n";
osf.write(buffer,buffer.length());
osf.close();

当我尝试使用以下方式读取该文件时,我意识到读取了比现在更多的字符。

std::ifstream is("MyTextFile.txt");
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);

char * buffer = new char [length];
is.read (buffer,length);

//work with buffer

delete[] buffer;

例如,如果文件包含spam\neggs\n,则此过程将读取12个字符而不是10个。前10个字符按预期spam\neggs\n,但还有2个字符具有整数值{ {1}}。 此外,只有在文件中存在65533时才会出现此问题。例如,如果文件包含\n,则没有问题。

问题是; 我做错了吗?或者这个程序不能正常工作吗?

奖金问:你能否建议一下阅读整个文件的替代方案?

注意:我发现这种方式here

3 个答案:

答案 0 :(得分:3)

只是一个想法,因为数字2对应于\n的计数:你在Windows上这样做吗?它可能与实际包含\r\n的文件有关。如果以二进制模式(std::ios::binary)打开文件会发生什么?

答案 1 :(得分:3)

问题是你写了字符串

"spam\neggs\n"

最初为ofstream,而未在std::ios::binary(或初始值)上设置open标记。这会导致运行时转换为"本机文本格式",i。例如,在输出上将每个\n转换为\r\n(就像在Windows操作系统上一样)。因此,在编写之后,文件的内容实际上是:

"spam\r\neggs\r\n"

(即12个字符)。 返回了

int length = is.tellg();

但是,当你尝试read 12个字符时,你得到了

"spam\neggs\n"

返回,因为运行时将每个\r\n转换回\n

作为最终建议,请,不要使用new char[length] ...使用std::stringreserve,这样您就赢了&#39 t泄漏内存等。如果你的文件可能非常大,也许同时整个文件淹没并不是一个好主意。

答案 2 :(得分:2)

  

您能否建议一次性阅读整个文件?

是:

std::ifstream is("MyTextFile.txt");
std::string str( std::istreambuf_iterator<char>{is}, {} ); // requires <iterator>

str现在包含该文件。这会解决您的问题吗?