-4

这是我的问题。我打开了一个 .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());
}
4

2 回答 2

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());

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

于 2012-07-12T17:52:22.643 回答
0

此类问题的调试过程是这样的:

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

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

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

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

于 2012-07-12T17:53:59.150 回答