【问题标题】:Reading data from file into a struct (C)将文件中的数据读入结构(C)
【发布时间】:2023-03-06 19:16:02
【问题描述】:

对不起,如果这种格式很乱,这是我第一次使用 stackoverflow。 我正在尝试使用fread 函数以512 个字节的块读取card.raw 文件,并将块的前4 个字节存储到s1-s4 中,其余508 个字节存储到字节数组中。但是,当我尝试运行它时,会出现分段错误。当我尝试调试时,调用fread函数后,argvoutptrinptrbuf的值都变成了NULL。为什么会这样,我做错了什么?

typedef uint8_t  BYTE;

//block of 512 bytes
typedef struct 
{
    BYTE s1;
    BYTE s2;
    BYTE s3;
    BYTE s4;
    BYTE image[508];
}
BUFFER;

int main(int argc, char* argv[])
{
    //opens memory card file
    FILE* inptr = fopen("card.raw", "r");

    int jpgcounter = 0;

    //creates jpg file
    char title[7];
    sprintf(title, "%d.jpg", jpgcounter);
    FILE* outptr = fopen(title, "a");

    //create buf (pointer) of type BUFFER
    BUFFER* buf;

    do
    {
        //creates buffer structure for storage of 512B blocks 
        buf = malloc(sizeof(BUFFER));

        //read 512 bytes at a time & stores every 512B block into a buffer struct buf
        fread(&buf, sizeof(BUFFER), 1, inptr);

        if(buf->s1 == 0xff && buf->s2 == 0xd8 && buf->s3 == 0xff)
        {

if 语句用于检查buf 的前3 个元素是否包含以下十六进制签名。我想在循环中使用malloc,以便以 512 字节的结构读取原始文件,决定如何处理 512 字节,然后连续释放它。

【问题讨论】:

  • 要将数据读入变量buf,还是读入buf持有指针的内存块?
  • fread(&buf, sizeof(BUFFER), 1, inptr); --> fread(buf, sizeof(BUFFER), 1, inptr);
  • 首先将错误检查添加到fopen()fread()。就目前而言,代码不会采取任何措施来测试访问文件是否有效。

标签: c struct segmentation-fault malloc fread


【解决方案1】:

使用fread(buf, sizeof(BUFFER), 1, inptr); 代替fread(&buf, sizeof(BUFFER), 1, inptr); 也以二进制模式打开文件进行读取,即"rb" 代替"r"

【讨论】:

  • 谢谢!但是为什么要以二进制模式打开文件呢?
  • 某些系统可能会以不同的方式对待"r""rb" 模式。例如,可以以不同方式处理行尾。您的数据似乎是纯二进制的,您不希望系统在读取时对其进行操作,因此以二进制模式打开它是安全的。
【解决方案2】:

当您将&buf 指针而不是buf 传递给fread 函数时,它将不会将您的数据写入分配的堆缓冲区,而是写入您的函数堆栈。由于x86 平台上的堆栈向较低的内存地址增长,这将覆盖堆栈上的所有内容,即在您的buf 变量之前 - 在您的情况下是局部变量、函数参数argcargv 等以及退货地址。堆栈已损坏,您会遇到分段错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2013-12-16
    相关资源
    最近更新 更多