在c中读取二进制文件的各个部分

时间:2015-03-28 18:50:56

标签: c file-io

我正在编写一个程序来读取二进制文件的特定部分,但我无法在文件中的正确位置读取正确长度的二进制文件。我已经试图弄清楚我一段时间以来做错了什么但没有成功。

这是我的代码看起来像

int project(char * rel, char * atr){  takes in the name of the relation to look in and the name of the attribute to look for

    char tmpstr[MAX_LEN+5], tmpstr2[MAX_LEN+5], attr[MAX_LEN+5], type[MAX_LEN+5], names[MAX_LEN+5];//attr is the attribute read by pass of fscanf()
    int numbytes = 0, numtups = 0, nummove = 0, skip = 0, i = 0;    //the length in bytes of the atr, number of tuples to read
    FILE* f1;
    FILE* f2;
    strcpy(tmpstr, rel);
    strncat(tmpstr,".sch", 4); // appends '.sch' extension to the file name
    if((f1 =(FILE*)fopen(tmpstr, "r")) == NULL){  // opens "InsertFileNameHere.sch"
        return -1;
    }
    if(fscanf(f1, "%d", &numattr) != 1){
        return -1;
    }
    strcpy(tmpstr2, rel);
    strncat(tmpstr2,".dat", 4); // appends '.dat' extension to the file name
    if((f2 =(FILE*)fopen(tmpstr2, "rb")) == NULL){  // opens "InsertFileNameHere.dat"
        return -1;
    }

    fscanf(f1, "%s", attr);  
    fscanf(f1, "%1s", type);
    fscanf(f1, "%d", &numbytes);
    while((strcmp(attr, atr) != 0) || numattr == 0){ //While the attr is = to the atr or you have run out of attributes to scan, keep scanning
        skip = skip + numbytes*2;
        fscanf(f1, "%s", attr);
        fscanf(f1, "%1s", type);
        fscanf(f1, "%d", &numbytes);
        numattr--;
        if(numattr == 0){
            return -2;
        }
        fseek(f2, skip, SEEK_CUR);
    }
    nummove = tuplen(rel) - numbytes*2;
    numtups = count(rel);
    printf("%d\n", nummove);
    while(i < numtups){
        fread(names, 1, numbytes*2, f2);
        fprintf(stdout, "%s\n", names);
        fseek(f2, skip, SEEK_CUR);
        i++;
    }
    puts("\n");
    fclose(f1);
    fclose(f2);
    return 1;

}

我用来测试此代码的文件如下:

Students.sch:此文件的第一行是文件中后续行的数量。在每一行上都是一个字符串,后跟要从二进制文件中读取的数据类型,然后是从二进制文件中读取的字节数。 该文件用于告诉程序如何读取二进制文件。

5
Name   S  25
Major  S  4
Minor  S  4
Totcr  I  4
Majcr  I  4

Students.dat:此文件包含要阅读的所有信息

536d 6974 682c 526f 6265 7274 0000 0000
0000 0000 0000 0000 0050 5359 0043 5349
0000 0000 3900 0000 2757 6f6f 6473 2c4a
616e 6500 0000 0000 0000 0000 0000 0000
0000 4353 4900 4255 5300 0000 0061 0000
0044 5261 6d73 6579 2c45 6c61 696e 6500
0000 0000 0000 0000 0000 0042 5553 0050
5359 0000 0000 6b00 0000 5857 6861 7274
6f6e 2c54 6f6d 0000 0000 0000 0000 0000
0000 0000 4255 5300 5053 5900 0000 0075
0000 0062 4261 6b65 722c 4e6f 726d 6100
0000 0000 0000 0000 0000 0000 0042 494f
0043 5349 0000 0000 2700 0000 19

任何帮助表示赞赏!谢谢!

1 个答案:

答案 0 :(得分:0)

你这里有问题

fscanf(f1, "%s", attr);
fscanf(f1, "%1s", type);
fscanf(f1, "%d", &numbytes);

你必须确保你读取了正确的值,所以你需要检查fscanf()的返回值,并且所有这些都可以放在这样的单个格式字符串中

if (fscanf(f1, "%s%1s%d", attr, type, &numbyts) != 3)
    /* ... there is a problem with the data, do not continue ... */

另外,为每个"%s"说明符提供长度修饰符以防止缓冲区溢出。