按字节读取文件
我有一个简单的程序:
#include <cstring>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
cout << "Creating test.txt file..." << endl;
// Writing to file
fstream fWrite;
fWrite.open("./_test_data/test.txt", fstream::out | fstream::trunc);
if (fWrite.fail()) {
cout << "Creating test.txt file failed!" << endl;
fWrite.close();
} else {
fWrite << (char) 0x09 << (char) 0x0A << (char) 0x0B;
fWrite << (char) 0x0C << (char) 0x0D << (char) 0x0E;
fWrite << flush;
fWrite.close();
cout << "test.txt file successfully created." << endl;
}
// Reading created file
cout << "Reading test.txt file..." << endl;
fstream fRead;
fRead.open("./_test_data/test.txt", fstream::in);
if (fRead.fail()) {
fRead.close();
} else {
char character;
while (true) {
fRead >> character;
if (fRead.eof()) {
cout << (int)character << endl;
cout << "EOF detected!" << endl;
break;
}
cout << (int)character << endl;
}
fRead.close();
}
return 0;
}
它应该只按 09 0A 0B 0C 0D 0E
的顺序写入字节,这样做没问题(由 hexdump 检查),但是当读取同一个文件时,它读取第一个字节为 < code>0E(= 十进制的 14)然后是 EOF...
Creating test.txt file...
test.txt file successfully created.
Reading test.txt file...
14
14
EOF detected!
为什么?
I have a simple program:
#include <cstring>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
cout << "Creating test.txt file..." << endl;
// Writing to file
fstream fWrite;
fWrite.open("./_test_data/test.txt", fstream::out | fstream::trunc);
if (fWrite.fail()) {
cout << "Creating test.txt file failed!" << endl;
fWrite.close();
} else {
fWrite << (char) 0x09 << (char) 0x0A << (char) 0x0B;
fWrite << (char) 0x0C << (char) 0x0D << (char) 0x0E;
fWrite << flush;
fWrite.close();
cout << "test.txt file successfully created." << endl;
}
// Reading created file
cout << "Reading test.txt file..." << endl;
fstream fRead;
fRead.open("./_test_data/test.txt", fstream::in);
if (fRead.fail()) {
fRead.close();
} else {
char character;
while (true) {
fRead >> character;
if (fRead.eof()) {
cout << (int)character << endl;
cout << "EOF detected!" << endl;
break;
}
cout << (int)character << endl;
}
fRead.close();
}
return 0;
}
It should just write bytes in order 09 0A 0B 0C 0D 0E
, which is done ok (checked by hexdump), but when reading the same file, it reads first byte as 0E
(= 14 in decimal) and then comes EOF...
Creating test.txt file...
test.txt file successfully created.
Reading test.txt file...
14
14
EOF detected!
Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用
fRead.read(&character,1)
而不是fRead >>字符
。但您也可以删除
cout << (int) 字符 << endl;
在 if 语句中。Use
fRead.read(&character,1)
instead offRead >> character
.But you can also delete the
cout << (int)character << endl;
in the if statement.以二进制模式打开文件:
fRead.open("...", fstream::in | fstream::binary);
- 这是为了防止文件层转换换行符序列。Open the file in binary mode:
fRead.open("...", fstream::in | fstream::binary);
- this is to keep the file layer from translating newline sequences.尝试
fRead>> std::noskipws
。读取流上的>>
运算符会跳过空格以获取下一个“有趣”的数据。考虑像hi There
这样的输入流。一次读取一个std::string
,您会得到hi
和there
,其中空格字符被忽略。类似地,一次读取一个字符,您会得到“hithere-”,而忽略空格字符。无法从 fRead 读取的字节都被视为空白,因此它们都被忽略。
fRead.read()
是一种解决方案(而且是一个好的解决方案)的原因是它执行未格式化的输入 - 它不关心空格。最后,您应该对程序进行以下其他更改:
std::cout
和std::endl
需要iostream
。fRead.open("./_test_data/test.txt", fstream::in | fstream::binary);
如果其中包含任何不可打印的字符,则需要以二进制格式打开测试文件(用于写入和读取)。
Try
fRead >> std::noskipws
. The>>
operator on read streams skips whitespaces to get to the next 'interesting' data. Consider an input stream likehi there
. Reading that astd::string
at a time, you'd gethi
andthere
, with the space character ignored. Simiarly, reading that a character at a time, you get -h-i-t-h-e-r-e-, with the space character ignored.The bytes that you couldn't read from fRead were all considered white space, so they were all ignored.
The reason that
fRead.read()
is a solution (and a good one) is that it does unformatted input -- it doesn't care about whitespace.Finally, you should make these other changes to your program:
You need
iostream
forstd::cout
andstd::endl
.fRead.open("./_test_data/test.txt", fstream::in | fstream::binary);
You need to open the test file in binary (both for writing and reading) if you are going to have any non-printable characters in it.