将二进制文件写入文件会从C中以前不相关的popen命令中提取不正确的数据

时间:2013-03-10 19:23:06

标签: c binary popen fwrite simultaneous

所以这段代码本身就起作用了,但是当我将它与我的主程序一起使用时,它会以某种方式拉入一些,似乎是完全不相关的代码部分并将其写入我正在编写的文件中......所有编译都没有问题,所以我知道这不是定义问题或指针问题,其他一切都写得正确,但不知怎的,我得到超过3200字节的结构与结构没有任何关系的东西,并写在文件中的地址0x1,它不是结构的任何部分......

struct a {
    unsigned long addr; //File address
    int sz; //Num Bytes
    unsigned long pos; // Buffer Address
};

// Many more than this, but you get the general struct idea..
struct a as[][3] = {
    {{ 0xF245, 5, 0x6F02C4 }},
    {{ 0x471D, 128, 0x65892 }},
    {{ 0x6198F, 12, 0xA4092 }}
}

//Failing code
        fdin = fopen(files[FIRSTFILE]->filename, "rb");

        fdout = fopen(files[SECONDFILE]->filename, "r+b");

        if (!fdin) {
            fprintf(stderr, "Unable to open %s\n", files[FIRSTFILE]->filename);
            fclose(fdin);
            cleanup(ONSCREEN);
            return EXIT_FAILURE;
        }

        if (!fdout) {
            fprintf(stderr, "Unable to open %s\n", files[SECONDFILE]->filename);
            fclose(fdout);
            fclose(fdin);
            cleanup(ONSCREEN);
            return EXIT_FAILURE;
        }

我这里有其他代码,但是没有从文件中读取并写入另一个这样的代码,但是在这里的某处,它在文件的地址0x1-0xC88范围内写错了至少3200个字节,并提取了我的数据在所有这些之前使用popen函数。

        for (int i = 0; i <= (sizeof(buffer) / sizeof(buffer[0])); i++) {

            memset(buffer, 0, sizeof(buffer));
            fseek(fdin, as[i]->pos, SEEK_SET);
            fread(buffer, 1, as[i]->sz, fdin);

            fseek(fdout, as[i]->addr, SEEK_SET);
            fwrite(buffer, 1, as[i]->sz, fdout);
        }

        if(fclose(fdout)==EOF || fclose(fdin)==EOF) {
            logit(ONSCREEN, "Error closing files.\n\n");
            cleanup(ONSCREEN);
            return EXIT_FAILURE;
        }
        fflush(fdin);
        fflush(fdout);

这是主程序中的一段代码,它以某种方式从中提取信息:

        sleep(1);
        memset(command, 0x00, 256);
        sprintf(command, "./somecommand");
        fp = popen(command, "r");
        if (fp == NULL) {
            logit(ONSCREEN, "popen failed.");
            cleanup(ONSCREEN);
            return EXIT_FAILURE;
        }

        while(fgets(store, sizeof(store), fp)) {
            if (strstr(store, "Expected Output")) {
            break;
            }
        }
        pclose(fp);
        fflush(fp);

同样,所有这些功能本身都很好,但是当它们组合在一个函数中时,它们不能很好地协同工作......文件(FILE * fp,* fdin,* fdout)的名称不同,并且存储字符数组的名称与缓冲区不同。我在这做错了什么?

对于在同一个函数中使用popen和fopen似乎是不安全的,或者我在这里没有正确清理的东西......?

1 个答案:

答案 0 :(得分:0)

在您的示例中,as[]有3个元素(您的真实代码可能有不同的数字)

// Many more than this, but you get the general struct idea..
struct a as[][3] = {
    {{ 0xF245, 5, 0x6F02C4 }},
    {{ 0x471D, 128, 0x65892 }},
    {{ 0x6198F, 12, 0xA4092 }}
}

但是,您使用buffer中的元素数量(在评论中,您说是char buffer[256]来对其进行索引:

   for (int i = 0; i <= (sizeof(buffer) / sizeof(buffer[0])); i++) {

        memset(buffer, 0, sizeof(buffer));
        fseek(fdin, as[i]->pos, SEEK_SET);
        fread(buffer, 1, as[i]->sz, fdin);

        fseek(fdout, as[i]->addr, SEEK_SET);
        fwrite(buffer, 1, as[i]->sz, fdout);
    }

for循环更改为(另请注意,测试已从<=更改为<):

  for (int i = 0; i < (sizeof(as) / sizeof(as[0])); i++)  

最后 - 我认为你通过使用as的二维数组无缘无故地使事情变得更加复杂(并且可能是错误的)。尝试:

struct a as[] = {
    { 0xF245, 5, 0x6F02C4 },
    { 0x471D, 128, 0x65892 },
    { 0x6198F, 12, 0xA4092 }
}


// ...
   for (int i = 0; i < (sizeof(as) / sizeof(as[0])); i++) {

        memset(buffer, 0, sizeof(buffer));
        fseek(fdin, as[i].pos, SEEK_SET);
        fread(buffer, 1, as[i].sz, fdin);

        fseek(fdout, as[i].addr, SEEK_SET);
        fwrite(buffer, 1, as[i].sz, fdout);
    }