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

时间:2012-07-12 17:28:34

标签: c++ file-io binary

这是我的问题。我打开了一个.jpg图像,并将每个字节写在一个用逗号分隔的.txt文件中。这是成功的。现在我想使用该txt文件来重建图像。 img.txt看起来像 255,216,255,224,0,16,74,70,73,70,0,1,1 ....... 下面的代码创建了image.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] = '\0';
            a[1] = '\0';
            a[2] = '\0';
            a[3] = '\0';
            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());
}

2 个答案:

答案 0 :(得分:1)

您编写的代码适用于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());

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

答案 1 :(得分:0)

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

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

我们的想法是输入一个小的输入,这样您就可以按照调试器中的各个步骤进行操作,并检查每条指令的行为是否符合您的预期。

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

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