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

lak*_*tha 1 c++ binary file-io byte

这是我的问题,我想打开一个.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]<<",";
}
Run Code Online (Sandbox Code Playgroud)

现在这个程序创建了带有十进制数字的image.txt,如下所示,4294967295,4294967256,4294967295,4294967264,0,16,74,70,73,70,0,1,......这里有些数字似乎是4字节long,s [i]只引用一个字节,那么(int)s [i]如何返回大于255的数字.请有人帮我这个....谢谢..

Naw*_*waz 13

它似乎在您的机器char签名.因此,当你输出一个负数时unsigned int,你会得到一个很大的价值.使用时,输出中的大值是负值char.请注意,当char签署,其值可-128127,但一个字节之间可0255.因此任何大于127该范围的值都会变为负数-128 to -1.

使用unsigned char如:

unsigned char *s;
Run Code Online (Sandbox Code Playgroud)

或者这样做:

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

也就是说,第一个投charunsigned 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);
Run Code Online (Sandbox Code Playgroud)

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

std::copy(buffer.begin(), 
          buffer.end(), 
          std::ostream_iterator<unsigned int>(std::cout, ","));
Run Code Online (Sandbox Code Playgroud)

要使所有这些工作正常,除了已在代码中添加的内容之外,还需要包含以下标题:

#include <vector>     //for vector
#include <iterator>   //for std::istream_iterator and std::ostream_iterator
#include <algorithm>  //for std::copy
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,这个地道的解决方案不使用指针new,它也不使用!