【问题标题】:Reading bytes one by one from binary file从二进制文件中逐个读取字节
【发布时间】:2012-07-11 05:33:00
【问题描述】:

这是我的问题,我想打开一个 .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,如下所示, 4294967295,4294967256,4294967295,4294967264,0,16,74,70,73,70,0,1,...... 这里有些数字似乎有 4 个字节长,s[i] 只指一个字节,所以 (int)s[i] 如何返回一个大于 255 的数字。请有人帮我解决这个问题....谢谢..

【问题讨论】:

  • 您正在读取的字符不是 0 到 255 的无符号数,而是 -128 到 +127 的有符号数。当您转换为 unsigned int 时,负数将被转换为大量正数。请尝试使用 unsigned char 数组。

标签: c++ file-io binary byte


【解决方案1】:

您的机器上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

如您所见,这个惯用的解决方案不使用 pointernew,也不使用 cast

【讨论】:

  • 好的。现在我成功创建了 image.txt 第二步是使用它并创建图像。首先我使用'stringstream ss;'并得到它的字符。我是这样做的。 'ss
  • 好的。现在我成功创建了 image.txt 第二步是使用它并创建图像回来。首先我使用了stringstream ss; 并得到了它的字符。我是这样做的。 ss&lt;&lt;(unsigned char)atoi(a) .然后是unsigned char* s=(ss.str()).c_str() 现在需要将其写入文件。 ofstream file("image2.jpg",ios::binary);fileo.write(s,sizeof(s));。我就是这样做的,问题是它在第一个空值之后不写任何东西。所以输出文件只有4个字节。那么将它写成二进制文件的正确方法是什么@Nawaz
  • @user1518082:为此开始另一个话题。别人会帮助你。我现在有点忙。 :-)
猜你喜欢
  • 2013-12-06
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多