c++以二进制方式读取文件.文件结束的问题
C++ reading a file in binary mode. Problems with END OF FILE
我正在学习c++,我必须以二进制模式读取文件。我是这样做的(遵循c++参考):
unsigned values[255];
unsigned total;
ifstream in ("test.txt", ifstream::binary);
while(in.good()){
unsigned val = in.get();
if(in.good()){
values[val]++;
total++;
cout << val <<endl;
}
}
in.close();
所以,我每个字节读取文件,直到in.good()
为真。为了了解发生了什么,我在while
的末尾放了一些cout
,下面是输出:
marco@iceland:~/workspace/huffman$ ./main
97
97
97
97
10
98
98
10
99
99
99
99
10
100
100
10
101
101
10
221497852
marco@iceland:~/workspace/huffman$
现在,输入文件"test.txt"就是:
aaaa
bb
cccc
dd
ee
所以一切都很完美,直到最后,那里有221497852。我猜是文件末尾的问题,但是我想不出是什么问题。
我正在使用编辑&debian机器上的g++(64位)。如有任何帮助,我将不胜感激。
许多谢谢,马可
fstream::get
返回int
值。这是问题之一。
fstream::read
:
// read a file into memory
#include <iostream> // std::cout
#include <fstream> // std::ifstream
int main () {
std::ifstream is ("test.txt", std::ifstream::binary);
if (is) {
// get length of file:
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);
char * buffer = new char [length];
std::cout << "Reading " << length << " characters... ";
// read data as a block:
is.read (buffer,length);
if (is)
std::cout << "all characters read successfully.";
else
std::cout << "error: only " << is.gcount() << " could be read";
is.close();
// ...buffer contains the entire file...
delete[] buffer;
}
return 0;
}
这不是istream::get()
的设计使用方式。使用这个函数的经典习惯用法是:
for ( int val = in.get(); val != EOF; val = in.get() ) {
// ...
}
或者更习惯的:
char ch;
while ( in.get( ch ) ) {
// ...
}
第一个循环实际上继承自C语言,其中in.get()
是相当于fgetc()
.
c++标准不清楚如果读取的字符值为负。fgetc()
需要一个值范围是[0...UCHAR_MAX]
,我认为可以安全地假设这里是intent。这是,至少,什么我用过的实现。但这并不影响你的输入。的实现如何解释标准,in.get()
的返回值必须在范围内[0...UCHAR_MAX]
或[CHAR_MIN...CHAR_MAX]
,否则必须为EOF(通常为1)。(我很确定其意图的原因是需要[0...UCHAR_MAX]
是因为,否则,您可能不需要能够区分文件结束和有效字符。)
和如果返回值是EOF(几乎总是)-1), failbit
应该设置,所以in.good()
将返回false
。没有允许使用in.get()
的情况返回221497852。这是我能想到的唯一解释你的结果是你的文件有一些字符位7设置在文件的末尾,表示实现是为this返回一个负数(但不是文件结束),因为它是一个字符),这会导致越界values[val]
中的索引,并且该索引是越界索引最终修改了val
。或者你的实现是当它返回end of时,没有设置failbit
文件。
std::ifstream in( "text.txt", std::ios_base::binary );
int ch = in.get();
while ( ch != std::istream::traits_type::eof() ) {
std::cout << ch << std::endl;
ch = in.get();
}
这避免了任何可能无效索引和任何类型的问题转换(尽管int
到unsigned
的转换很好)定义)。另外,出于好奇(因为我只能访问vc++)在这里),您可以尝试替换in
如下:
std::istringstream in( "nxE5" );
我希望得到:
10
233
(假设8位字节和基于ASCII的代码集。这两个)
我终于弄明白了。显然,问题似乎不是由于任何代码。问题已经解决了。它总是在文件末尾追加一个换行符。其他编辑器(如vim)也会出现这种情况。对于某些编辑器,这可以配置为不附加任何内容,但在gedit中,这显然是不可能的。https://askubuntu.com/questions/13317/how-to-stop-gedit-gvim-vim-nano-from-adding-end-of-file-newline-char
为每个问我的人干杯
马可
- 通过终端在文件中输入时检测EOF(文件结束)时出现问题
- 带有文件结束函数的 while 循环重复输出文件中的最后一个数字两次
- 触发文件结束的原因
- 从 ifstream 读取,直到文件结束
- C++:读取.BMP文件时出现问题;文件结束时间早于预期
- C 功能:读取直到文件结束 - 查找代码中的错误
- C :在文件结束时GetLine冻结
- 表示文件结束
- 如何让程序知道当我使用 while(cin>> 时文件结束
- 文件结束输入不起作用
- 使用RAII写入文件结束标记
- 在文件结束后继续输入
- .hpp 文件上的意外文件结束错误
- 读取:ASIO中的文件结束.插座为什么要关上
- 防止包括从hxx(模板定义)文件结束头
- fstream对象的文件结束
- 文件不会重复自己,直到文件结束
- 文件结束检查不起作用 (C++)
- 语法错误,意外的标记,期望文件结束
- 如何模拟文件结束