所以,我目前正在为我的Unix操作系统类进行系统编程。这个程序所要做的就是读取一个二进制文件并将这些行输出到一个CSV文件。我觉得我差不多做完了,但不知为什么我老是犯错误。
澄清:
fd1=输入文件,
fd2=输出文件
numrecs=输入文件中的记录数。
在main()的某个地方:

for(i=0;i<numrecs;i++){
    if((bin2csv(fd1, fd2)) == -1){
        printf("Error converting data.\n");
    }
}

int bin2csv(fd1, fd2){
    bin_record rec;
    char buffer[100];
    int buflen;
    strncpy(buffer,"\0", 100); /* fill buffer with NULL */
    recs = &rec;

    /* read in a record */
    if((buflen = read(fd1, &recs, sizeof(recs))) < 0){
        printf("Fatal Error: Data could not be read.\n");
        return -1;
    }

   sprintf(buffer, "%d, %s, %s, %f, %d\n", recs->id, recs->lname, recs->fname, recs->gpa, recs->iq);
   printf("%s\n", buffer);
   write(fd2, buffer, sizeof(buffer));
   return 0;
}

segfault出现在“sprintf(buffer,etc…”行上,但是,我不明白为什么会发生这种情况。
这是gdb指出的错误:
程序接收信号SIGSEGV,分段故障。
0x0000000100000c87位于bin2csv(fd1=3,fd2=4),位于bin2csv.c:25
25个sprintf(缓冲区,“%d、%s、%s、%f、%d\n”、recs->id、recs->lname,
记录->fname,记录->gpa,记录->iq);
希望这是足够的信息谢谢!

最佳答案

看起来recs是一个指针您正在将字节直接读取到该指针中,就像从文件读取原始内存地址一样:

read(fd1, &recs, sizeof(recs))

然后你开始在呼叫sprintf时使用它繁荣!
实际上根本没有理由使用它(它是全球性的吗?)... 即使您使用recs = &rec初始化了它,并且假设您没有丢弃它,它仍然不会包含该函数之外的有效地址这是因为rec是一个局部变量。
所以,直接读到这样的rec
read(fd1, &rec, sizeof(rec))

然后在sprintf行中,使用rec.id而不是recs->id(etc)。

10-01 11:36