首页 文章

读取.dat文件时出现分段错误

提问于
浏览
1

现在,我正在研究一个示例代码,我希望稍后将其集成到我的程序中 . 基本上我要做的是逐字节读取.dat文件并解释数据(即解释引导扇区以输出扇区大小,保留扇区等)

为此,我逐字节地读取数据,并使用https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html#ss1.3的fat12中的描述,将数据转换为我想要的信息 . 现在,我可以从文件中提取单个字节(是否正确地假设拉出的数据是十六进制的?) . 但是,我需要两个字节才能有意义 . 因此,我需要将两个字节合并为一个,将十六进制数据转换为十进制并输出信息 . 不幸的是,现在,我想出了什么是错的 . 提前致谢!

int main(int argc,char ** argv){

FILE *fp ,*fptest;
long lSize;
char *buffer;

//Open file
fptest= open("fat_volume.dat", "rb");

//Read file into buffer
fread(buffer,1,512,fptest);

//Parse the boot sector
char tmpA, tmpB;
tmpA = buffer[10]; //First byte
tmpB = buffer[11]; //Second byte

//Combine the two bytes into one
char combinedBytes[3];
strcpy (combinedBytes, tmpA);
strcat (combinedBytes, tmpB);

//Hex to decimal converter
long int li1;
li1 = strtol (combinedBytes,NULL,16);
printf ("The sector size is: %ld.\n", li1);

return 0;

}

2 回答

  • 0

    您正在读入一个从未为其分配内存的缓冲区 .

    你现在正在尝试的是从内存中的一些垃圾值中读取,谁知道,这几乎总是导致分段错误 .

    使用:

    char *buffer = malloc(512 * sizeof(char)); // this allocates 512 times the size of a single char of memory
    

    如果你没有将malloc中的数字指定为特定大小(例如malloc(512),则该数字以字节为单位,但我认为最好始终包含它 .

    此特定错误称为dereferencing a null pointer

    EDIT:

    我设法运行此代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (int argc, char **argv)
    {  
        FILE *fp ,*fptest;
        long lSize;
        char *buffer;
    
        //Open file
        fptest = fopen("input.txt", "rb");
    
        if (fptest == NULL)
        {
            printf("Error occurred when opening file");
            return 1;
        }
    
        buffer = malloc(sizeof(char) * 512);
        //Read file into buffer
        fread(buffer,1,512,fptest);
    
        //Parse the boot sector
        char tmpA, tmpB;
        tmpA = buffer[10]; //First byte
        tmpB = buffer[11]; //Second byte
    
        //Combine the two bytes into one
        char combinedBytes[3];
        strcpy (combinedBytes, &tmpA);
        strcat (combinedBytes, &tmpB);
    
        //Hex to decimal converter
        long int li1;
        li1 = strtol (combinedBytes,NULL,16);
        printf ("The sector size is: %ld.\n", li1);
    
        return 0;
    }
    

    您还使用了函数 open() ,它必须是 fopen() ,并且您需要将tmpA和tmpB的地址传递给strcpy和strcat .

    这就是为什么我不明白你的编译器没有给出任何错误或警告的原因 .

  • 1

    你必须分配 buffer ;例如

    char buffer[512];
    

    要么

    char *buffer = malloc(512);
    

    编辑:

    字符串操作

    strcpy (combinedBytes, tmpA);
    strcat (combinedBytes, tmpB);
    

    没有意义,访问/复制太多数据(编译器会警告你这个!) .

    我建议读取值为

    unsigned char tmpA = buffer[10];
    unsigned char tmpB = buffer[11];
    
    unsigned int tmp = (tmpA << 8) | (tmpB << 0);  /* or revert in in case of
                                                      little-endian */
    

    为了提高效率,我会把它写成

    struct fat_header {
        uint8_t pad0[10];
        uint16_t my_val;
        uint8_t pad1[500];
    } __attribute__((__packed__));      /* this is not portable and for gcc! */
    
    ...
    
    struct fat_header  hdr;
    
    fread(&hdr, 1, sizeof hdr, f);
    uint16_t val = be16toh(hdr.my_val); /* or le16toh() in case of le */
    

相关问题