将内容从一个文件复制到另一个文件,分段错误

时间:2013-03-19 00:25:53

标签: c cs50

我试图从一个大的.raw文件中逐个复制50个jpeg,但是目前我遇到了分段错误错误。这是我的代码:

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

typedef uint8_t BYTE;

//SOI - 0xFF 0xD8
//EOI - 0xFF 0xD9
//APPn - 0xFF 0xEn    
int main(void)
{
    //FAT - 512 bytes per block
    BYTE block[512];

    //open file containing pictures
    FILE* card_file = fopen("card.raw", "rd");

    FILE* jpeg_file;

    //make sure the file opened without errors
    if (card_file == NULL)
    {
        printf("something went wrong and file could not be opened");
        return 1;
    }

    int i = 0;
    while (fread(&block, sizeof(BYTE), 512, card_file) != 0)
    {
        //jpeg start signature
        if(block[0] == 0xFF && block[1] == 0xD8)
        {
            i++;
            if(jpeg_file != NULL)
                fclose(jpeg_file);

            //create a new jpeg file to copy bytes to
            jpeg_file = fopen((char*)i, "w+");
        }

        //write 512 bytes to a jpeg file
        if(jpeg_file != NULL)
            fwrite(block, sizeof(block), 1, jpeg_file);
    }

    fclose(card_file);
return 0;
}

当我通过GDB运行时,我的代码一直到if(block [0] == 0xFF&amp;&amp; block 1 == 0xD8),然后它跳过条件并发生分段错误。我不知道可能是什么造成了这种情况。 这是一个截图: enter image description here

代码已更新:

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

typedef uint8_t BYTE;

/*struct jpg*/
/*{*/
/*    BYTE soi[2] = { 0xFF, 0xD8 };*/
/*    BYTE eoi[2] = { 0xFF, 0xD9 };*/
/*};*/

//SOI - 0xFF 0xD8
//EOI - 0xFF 0xD9
//APPn - 0xFF 0xEn    
int main(void)
{
    //FAT - 512 bytes per block
    BYTE block[512];

    //jpeg name
    char name[6];

    bool is_open = false;

    //JPEG
    //struct jpg image;

    //open file containing pictures
    FILE* card_file = fopen("card.raw", "r");

    FILE* jpeg_file;

    //make sure the file opened without errors
    if (card_file == NULL)
    {
        printf("something went wrong and file could not be opened");
        return 1;
    }

    int i = 0;
    while (fread(block, sizeof(BYTE), 512, card_file) != 0)
    {
        //jpeg start signature
        if ((block[0] == 0xFF) && (block[1] == 0xD8) && (block[2] == 0xFF) && ((block[3] == 0xe1) || (block[3] == 0xe0)))
        {
            //assign jpeg name
            sprintf(name, "%d.jpg", i++);
            if(is_open)
                fclose(jpeg_file);

            //create a new jpeg file to copy bytes to
            jpeg_file = fopen(name, "a+");
            is_open = true;
        }

        //write 512 bytes to a jpeg file
        if(is_open)
            fwrite(block, sizeof(block), 1, jpeg_file);
    }

    fclose(jpeg_file);
    fclose(card_file);
return 0;
}

现在它并没有崩溃,但是50个jpeg中只有9个被正确恢复。 cs50.h就是这样我可以访问bool类型。什么是写50个文件的更好方法?我似乎对我的布尔有一个合乎逻辑的缺陷。

2 个答案:

答案 0 :(得分:1)

fopen((char*)i, "w+");完全无效。您正在将一个整数作为指针投射,这将会崩溃。

您需要将数字格式化为文件名:

char path[PATH_MAX];
sprintf(path, "%d", i);
fopen(path, "w+");

您也没有初始化jpeg_file - 如果条件失败,jpeg_file将是一个狂野指针,它也会崩溃。您应该将jpeg_file初始化为NULL

答案 1 :(得分:0)

fread调用中,您应该传递数组的地址。因此,该陈述应为fread(block, sizeof(BYTE), 512, card_file)

<强>后记:

  1. 在您的代码中,假设输入文件的大小是512的整数倍,这不是 JPEG 文件的情况。最后一个fread可能返回一个小于512的数字,需要在您的实现逻辑中处理。因此,要写入的元素数量应由fread

  2. 的返回值确定
  3. 循环结束后,您需要关闭jpeg_file指针。

  4. 最后,由于您使用的是 JPEG ,因此您可能希望使用缩略图处理 EXIF 文件的大小写。在这种情况下,您将获得2 SOI (图像起点)标记。