从二进制文件中逐个读取字节

Reading bytes one by one from binary file

本文关键字:读取 字节 二进制文件      更新时间:2023-10-16

这是我的问题,我想打开一个.jpg文件,并将每个字节以逗号分隔的十进制数(0-255)写入另一个.txt文件。现在,它应该能够使用该txt文件再次构建.jpf文件。我就是这么想的。

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
long x;
char *s;
ifstream ifs("image.jpg",ios::binary);
ifs.seekg(0,ios::end);
x=ifs.tellg();
ifs.seekg(0,ios::beg);
s=new char[x];
ifs.read(s,x);
ifs.close();
ofstream is("image.txt");
for(int i=0;i<x;i++){
is<<(unsigned int)s[i]<<",";
}

现在这个程序用十进制数字创建image.txt,如下所示,429496729542949672564294967295429494967264,0,16,74,70,73,70,0,1,。。。。。。这里有些数字似乎是4字节长,s[i]只指一个字节,那么(int)s[i]怎么能返回一个大于255的大数字呢。请有人帮我做这件事。。。。谢谢

在您的机器上,char似乎已签名。所以当你把一个负数转换成unsigned int时,你会得到一个很大的值。当使用char表示时,输出中的大值为负值。请注意,当char有符号时,其值可以是-128127,但字节可以在0255之间。因此,任何大于127的值在范围-128 to -1之间都将变为负值。

使用unsigned char作为:

unsigned char *s;

或者这样做:

is<< static_cast<unsigned int> (static_cast<unsigned char>(s[i]) )<<",";
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                casting to unsigned char first
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
               then casting to unsigned int 

也就是说,先将char强制转换为unsigned char,然后再强制转换为unsigned int


这就是你所面临的问题。现在请注意文体和习语。在C++中,应尽可能避免使用new。在您的情况下,您可以将std::vector用作:

//define file stream object, and open the file
std::ifstream file("image.jpg",ios::binary);
//prepare iterator pairs to iterate the file content!
std::istream_iterator<unsigned char> begin(file), end;
//reading the file content using the iterator!
std::vector<unsigned char> buffer(begin,end);

最后一行将文件中的所有数据读取到buffer中。现在您可以将它们打印为:

std::copy(buffer.begin(), 
          buffer.end(), 
          std::ostream_iterator<unsigned int>(std::cout, ","));

为了使所有这些都起作用,除了您已经在代码中添加的内容外,还需要包括以下标题:

#include <vector>     //for vector
#include <iterator>   //for std::istream_iterator and std::ostream_iterator
#include <algorithm>  //for std::copy

正如您所看到的,此惯用解决方案不使用指针new,也不使用强制转换