istream::seekg与ios_base::end是否可靠?



假设我用这种方式创建了一个文件:

std::ofstream osf("MyTextFile.txt");
string buffer="spamneggsn";
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;

例如,如果文件包含spamneggsn,则此过程读取12个字符而不是10个字符。如预期的那样,前10个字符是spamneggsn,但还有2个字符具有整数值65533。而且,只有在文件中存在n时才会发生此问题。例如,如果文件包含spamteggst,则没有问题。

问题是;我做错什么了吗?或者这个程序没有按照它应该做的那样工作?

附加问:你能建议一次读取整个文件的替代方法吗?

问题是你写了字符串

"spamneggsn"

初始化为ofstream,没有在open(或初始化器)上设置std::ios::binary标志。这将导致运行时转换为"本地文本格式",即将输出上的每个n转换为rn(正如您在Windows操作系统上一样)。因此,在写入之后,文件的内容实际上是:

"spamrneggsrn"

(我。E . 12个字符)。

返回
int length = is.tellg();

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

"spamneggsn"

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

作为最后的建议,请,不要使用new char[length]…使用std::stringreserve,这样你就不会泄漏内存等。如果你的文件可能非常大,那么一次性将整个文件存储到内存中也不是一个好主意。

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

你能建议一次读取整个文件的替代方法吗?

Yes:

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

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

最新更新