我找到了一段代码,它提供了文本文件的大小:
ifstream file("xmlfile.xml",ios::in);
//get size
file.seekg (0, ios::end);
int length = file.tellg();
file.seekg (0, ios::beg);
// allocate memory:
char* buffer = new char [length];
// read data as a block:
file.read (buffer,length);
file.close();
buffer[length-1] = '\0';
printf("%s",buffer);
问题在于我想要读取一个小的xml文件,完全读取它,但最后留下了许多'='符号,因为我发现它们等于文件中CR的数量。将EOL切换到Unix解决了这个问题,但为什么在Windows EOL中打印有问题?
示例xml:
<?xml version="1.0"?>
<catalog>
(EOL)
printf打印的是什么:
<?xml version="1.0"?>
<catalog>
══════
答案 0 :(得分:3)
问题出现是因为Windows在每行的末尾使用了回车符+换行符,而Linux只使用其中一个。
您的ifstream以文字模式打开。它返回文本文件的绝对大小,但随后您指示它读取许多 text 字符。它似乎丢弃了Windows不会自动使用的额外字符,并且您最终会读取文件的末尾。
要纠正此问题,可以使用.gcount()来获取读取的字符数。
答案 1 :(得分:3)
有两个问题。
使用seek
和tell
获取文件大小将告诉您文件中有多少字节。光盘上的Windows EOL是两个字节。但是,当您在文本模式下打开的文件上使用read
读取它时,EOL将在内存中变为一个字节。您可以通过以二进制模式打开文件来解决此问题:
ifstream file("xmlfile.xml",ios::in | ios::binary);
另一个问题是,如果要将文件的内容视为以空字符结尾的字符串,则需要为NULL终止符分配额外的空间。就目前而言,您将使用NULL覆盖文件的最后一个字节。你应该这样做:
char* buffer = new char [length+1];
和
buffer[length] = '\0';
答案 2 :(得分:2)
如果我理解正在发生的事情,tellg
会告诉您位置以字节为单位,但在阅读过程中,Windows行结尾将转换为普通'\n
';因此,buffer[length]
引用的位置是在“缺失”CR数量的“真实”结束之后。
为避免此问题,请在读取文件后调用file.gcount()
以获取上次读取时读取的字符数,并将其用作终止缓冲区的位置。