将二进制字符串写入二进制文件

writing binary string to binary file

本文关键字:二进制文件 字符串 二进制      更新时间:2023-10-16

这是我的问题。 我打开了一个.jpg图像,并将其每个字节写入一个用逗号分隔的.txt文件中。 这是成功的。 现在我想使用该 txt 文件重建映像。 IMG.txt看起来像255,216,255,224,0,16,74,70,73,70,0,1,1.......以下代码创建了图像.jpg,如果为原始图像,则具有大小,但图像不可见。我期待有人的帮助...

#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include<cstdlib>
using namespace std;
int main(){
    char *s;
    long x;
    ifstream is("D:\test\img.txt");
    is.seekg(0,ios::end);
    x=is.tellg();
    is.seekg(0,ios::beg);
    s=new char[x];
    is.read(s,x);
    is.close();
    stringstream str;
    char a[4];
    int y = 0;
    for(int i=0; i<=x; i++) {
        if (s[i] != ',') {
            a[y] = s[i];
            y = y + 1;
        }
        if (s[i] == ',') {
            str << (unsigned char)atoi(a);
            a[0] = '';
            a[1] = '';
            a[2] = '';
            a[3] = '';
            y = 0;
        }
    }
    const char *ss=(str.str()).c_str();
    ofstream ex("D:\test\test.txt");
    ex << ss;
    ofstream fileo("D:\test\image.jpg",ios::binary);
    fileo.write(ss,(str.str()).length());
}

您编写的代码适用于Visual Studio 10 SP1。 但是,有一个微妙的错误取决于您的 STL 实现(和运气(:

您的代码:

const char *ss=(str.str()).c_str();

正在使用已超出范围的临时。 ss所指向的很可能是此行执行后立即(或将来的任何时间(的垃圾。 原因是std::stringstream::str()返回字符串的副本,可以安全地在此副本上调用std::string::c_str(),但是一旦原始(临时(超出范围,该指针将无效。

若要解决此问题,请确保将字符串从 stringstream 对象中复制出来,以便知道生存期,如下所示:

std::string contents = str.str();
ofstream ex("D:\Profile2.jpg.txt");
ex<<contents;
ofstream fileo("D:\Profile2.jpg",ios::binary);
fileo.write(contents.c_str(), contents.length());

重申一下,这两个版本都对我有用,但我提出的版本实际上是设计工作,而不是运气。

此类问题的调试过程如下:

  • 您可以创建尽可能小的输入(内部带有字母"a"并另存为"Test01.jpg"的文本文件(并运行转换算法
  • 您可以使用您的领域知识确定预期结果是什么
  • 检查输出并确定它是否是预期结果
  • 如果是,则继续测试"TXT到JPG"转换
  • 否则,您可以更改"JPG 到 TXT"算法或您的领域知识
  • 假设 txt 输出是预期结果,则运行"txt 到 jpg">
  • 如果结果与原始文件匹配(请记住,"JPG"只是一个扩展名,您仍然可以在记事本中打开文件 - 或者更好的是,十六进制编辑器(,然后更改输入并再次测试
  • 否则,您将更改算法

这个想法是有一个小的输入,以便您可以按照调试器中的各个步骤进行操作,并检查每条指令的行为方式是否与您认为应该的行为方式相同。

由于输出与输入不匹配,因此显然某些内容无法按预期工作。能够解决自己的问题比在一个特定问题上获得帮助重要得多。

我也会delete我的缓冲区(s上面的代码中(,即使程序退出时操作系统回收内存,这也是一个好习惯。