我可以用c++中的istream读取二进制数据吗
Can I read in binary data with istream in c++?
现在我正在使用istream读取数据。我有两个文本,我想以字符串和数字的形式读取,还有散列,它们被读取到字符数组中。由于散列实际上是随机的,所以当我试图读回它并点击EOF(这是散列的一部分)时,我遇到了障碍。有没有一种方法可以在不使用fread的情况下实现这一点。此外,是否有同时使用istream和fread的方法?我不必手动解析整数和字符串。最后,使用fgets获取未知长度字符串的最佳方法是什么。
谢谢,Eric
编辑:这是代码:
string dummy;
ifstream in(fileName);
for(int i=0; i<numVals; i++)
{
int hashLen;
in>>hashLen;
char cc;
in.get(cc);//Get the space in between
cout<<"Got first byte: "<<(int)cc<<endl;
char * hashChars = new char[hashLen];
in.read(hashChars, hashLen);
for(int j =0; j <hashLen; j++)
{
char c = hashChars[j];
unsigned char cc = reinterpret_cast<unsigned char&>(c);
cout<<"Got byte: "<<(int)c<<(int)cc<<endl;
if(in.fail())
{
cout<<"Failed! "<<in.eof()<<" "<<in.bad()<<endl;
}
}
delete hashChars;
getline(in,dummy);//get a dummy line
cout<<"Dummy: "<<dummy<<" numvals: "<<numVals<<" i: "<<i<<" hashLength: "<<hashLen<<endl;
}
我的输出看起来像:
1> 得到第一个字节:32
1> 得到字节:4 4
1> 获取字节:-14 242
1> 获取字节:108 108
1> 得到字节:87 87
1> 得到字节:113 113
1> 获取字节:-116 140
1> 获取字节:-106 150
1> 获取字节:-35 221
1> 获取字节:0 0
1> 获取字节:-91 165
1> 获取字节:39 39
1> 获取字节:111 111
1> 得到字节:7 7
1> 获取字节:126 126
1> 获取字节:16 16
1> 获取字节:-42 214
1> 伪:numvals:35 i:12 hashLength:16
1> 得到第一个字节:32
1> 得到字节:14 14
1> 失败!10
1> 获取字节:-65 191
1> 失败!10
1> 获取字节:-107 149
1> 失败!10
1> 获取字节:-44 212
1> 失败!10
1> 获取字节:-60 196
1> 失败!10
1> 获取字节:-51 205
1> 失败!10
1> 获取字节:-51 205
1> 失败!1 0
读取二进制数据时,通常需要使用标志std::ios_base::binary
打开std::ifstream
。由此产生的差异相当小,但它们通常很重要。
在你的代码中有一些奇怪的地方你可能想修复:
- 您总是需要在读取后检查操作是否成功,例如使用
if (in.read(hashChars, hashLen)) { ... }
- 不需要使用
reinterpret_cast<...>()
,它总是具有实现定义的语义。您应该使用static_cast<unsigned char>(c)
- 您分配了一个字符数组,但使用
delete p
释放它。您需要使用delete[] p
。使用delete p
会导致未定义的行为。实际上根本不需要使用new
和delete
,因为std::vector<char> hashChars(hashLen)
可以自动管理内存
上面的请求中嵌入了一些[残缺的]问题(因此问题/答案是对所问内容的猜测):
- 你能在同一个流上混合
std::istream::read()
和fread()
吗(我想这就是问题所在):除非流恰好是std::cin
,它与stdin
从同一个源读取,否则不能立即混合。如果要在同一文件中同时使用std::istream::read()
和fread()
,则需要用合适的std::streambuf
包装FILE*
,并用相应的对象初始化std::istream
- 如何使用
fgets()
读取任意大小的行?你不能。fgets()
的缓冲区在尝试填充之前被分配,并且总是可以在到达换行符之前被填充。但是,您可以使用std::getline()
读取任意长的行。如果您只是想跳过这一行,则可以在使用std::istream
时使用in.ignore(std::numeric_limits<std::streamsize>::max(), 'n')
。我不知道FILE*
是否也有类似的操作
- 如何从dicom文件中读取二进制数据
- 如何在Qt中从数据库中检索二进制数据?
- readsome() 适合在 Windows 上读取二进制数据吗?
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 将包含二进制数据的 QByteArray 传递到按值运行
- 如何在 c++ 中生成十六进制二进制数据的 sha256 哈希?
- 在处理网络、二进制数据和序列化时应使用流或容器
- 我能确定从文件中读取的 32 字节二进制数据等于 256 位吗?
- C++:如何通过 curl 调用使用 HTTP post 请求发送二进制数据(protobuf 数据)
- 使用二进制数据更新 PostgreSQL 表
- 使用二进制数据和无符号字符
- sd_journal_send发送二进制数据.如何使用日志检索数据?
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- 将文本和二进制数据连接到一个文件中
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 将整数的二进制数据转换为浮点数
- 使用 CMake 在可执行文件中嵌入二进制数据
- 二进制数据作为命令行参数
- 如何访问文件的二进制数据?
- 返回二进制数据的通用方式,而无需原始指针