所以,我目前正在为我的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)。