【问题标题】:Trouble using fread to change struct value C使用 fread 更改结构值 C 时遇到问题
【发布时间】:2013-04-03 05:08:41
【问题描述】:

我的问题是,我认为……一切正常,但实际的块变量没有改变。它是 BLOCK 大小,为 512 个字节,其中第一个字节被列为 block.head[0,1,2,3]。所以我的程序使用 block.head[] 来查看它正在读入的文件块的前四个字节是否匹配。

所以我认为正在发生的事情是它正在将 BLOCK 数量读入文件,但实际上并没有改变 block.head 变量。因此,即使它正在读取文件的某个部分,它也不会更改它需要比较的变量。我认为在 fread 参数中写 &block 会改变这一点,但事实并非如此。

有什么想法吗?

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t  BYTE;
typedef uint32_t DWORD;

typedef struct
{
    BYTE head[4];
    DWORD restofblock[127];
}
BLOCK;

int main (void)
{
    //open card.raw
    FILE* fp = fopen("file.file", "r");

    //default name for new files is new000.jpg
    char outfile[10] = "new000.jpg";

    // char* infile = argv[1];
    // FILE* inptr = fopen(infile, "r");

    FILE* output;
    output = NULL;

    //define a black
    BLOCK block;

    //While we haven't read past the end of the file
    while (block.head[1] != EOF)
    {
        //read a BLOCK of the .raw file
        fread(&block, sizeof(BLOCK), 1, fp);

        //dual "if" statements because I couldn't figure out how to combine them
        //checks to see if the first four BYTES of BLOCK block are a JPEG header
        if (block.head[0] == 255 && block.head[1] == 231 && block.head[2] == 255)
        {
            if (block.head[3] == 239 || block.head[3] == 240)
            {

                fclose(output);

                //designating c as a placeholder for the 3rd 0 in the filename
                //checks to see if c is above or equal to "9".
                //if it is, it resets "9" to "0" and increments the 2nd 0 in the filename by 1
                //if it isn't it adds 1 to the 3rd "0"
                char c = (outfile[5]);
                if (c >= 71) //71 is the ascii equivalent of 9
                {
                    outfile[5] -= 9;
                    outfile[4]++;
                }
                else
                    outfile[5]++;

                //Read forward 1 BLOCK to check for EOF, if EOF is false, read back to original position and print. 
                //Otherwise read back to initial position.
                fread(&block, sizeof(BLOCK), 1, fp);
                if(block.head[0] != EOF)
                {
                    fread(&block, -sizeof(BLOCK), 1, fp);
                    output = fopen(outfile, "w");
                }
                else
                    fread(&block, -sizeof(BLOCK), 1, fp);
            }
        }
        if (output == NULL);

        else
            fwrite(&block, sizeof(BLOCK), 1, output);

   }
    fclose(output);
    fclose(fp);
    return 0;
}

【问题讨论】:

  • 也许快速回顾一下fread() 可能会对您有所帮助。 size 参数没有签名,你不能像你想象的那样使用fread()“倒带”。请考虑使用fseek(),因为你现在拥有的东西没有机会工作。
  • 阅读man fread:“fread() 不区分文件结尾和错误,调用者必须使用 feof(3) 和 ferror(3) 来确定发生了什么。”最好使用普通的readif(block.head[0] != EOF) 也永远不会像 EOF = -1 那样工作,但你的 head 是未签名的。另外,正如我之前提到的,fread 不返回 EOF!
  • 我认为,mmap 和指向 BLOCK 的指针的递增以及 mmaped 文件的大小控制会很容易。

标签: c struct fwrite fread


【解决方案1】:

代替

while (block.head[1] != EOF)

你应该这样读:

while (fread(&block, sizeof(BLOCK), 1, fp) > 0)

我找不到您分配head[1] = EOF 的任何地方,此外最初block.head[1] 具有垃圾值。因为您没有初始化它并在 while 条件下使用。

【讨论】:

  • 现在我把它放进去,有一个分段错误,它只写入一个 0 字节大的文件。即它创建它,然后崩溃
猜你喜欢
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 1970-01-01
相关资源
最近更新 更多