Итак, в настоящее время я работаю над системным программированием для своего класса ОС Unix. Все, что должна сделать эта программа, это прочитать двоичный файл и вывести строки в CSV-файл. Я чувствую, что почти закончил, но по какой-то причине я продолжаю получать segfault.
Для уточнения: 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 (буфер и т. д.);» однако я не могу понять, почему это происходит.
Это ошибка, которую выдает gdb:
Программа получила сигнал SIGSEGV, ошибка сегментации.
0x0000000100000c87 в bin2csv (fd1=3, fd2=4) в bin2csv.c:25
25 sprintf(buffer, "%d, %s, %s, %f, %d\n", записи->id, записи->lname,
записи->fname, записи->gpa, записи->iq);
Надеюсь, этой информации достаточно. Спасибо!
recs->...
, вы можете предположить, что recs не инициализируется должным образом. Проверьте, было ли этоNULL
прямо перед этим, и если нет, продолжайте копать. - person Ricky Mutschlechner   schedule 16.12.2015bin_record
. - person chux - Reinstate Monica   schedule 16.12.2015strncpy(buffer,"\0", 100); /* fill buffer with NULL */
Это не заполнит буфер символами NUL, посколькуstrncpy()
копирует максимальное количество байтов, но все равно останавливает копирование, когда в источнике встречается первый символ NUL. - person Andrew Henle   schedule 16.12.2015int bin2csv(fd1, fd2){
не будет компилироваться. Возможно, вы имели в виду: (при использованииopen()
)int bin2csv( int fd1, int fd2 )
- person user3629249   schedule 16.12.2015strncpy(buffer,"\0", 100);
это скопирует до 0 байтов, а затем добавит «\ 0», вероятно, не то, что вы хотите. Предложить:memset( buffer, '\0', sizeof(buffer) );
- person user3629249   schedule 16.12.2015recs = &rec;
, rec определяется как struct , а не как указатель, и эта строка попросит указать на себя, возможно, не то, что вы хотите, предложите удалить эту строку. - person user3629249   schedule 16.12.2015if((buflen = read(fd1, &recs, sizeof(recs))) < 0){
и перед тем, как использовать содержимоеrecs
для заполнения массива buffer[], необходимо проверитьbuflen==0
(то есть EOF) иbuflen < sizeof(recs)
(недостаточно символов в файле для чтения полногоrecs
. - person user3629249   schedule 16.12.2015recs->lname, recs->fname
не имеют фиксированного размера, нельзя быть уверенным, что вся запись прочитана (а не часть следующей записи). Если нет фиксированной длины для этих двух полей, настоятельно рекомендуется читать по одному символу за раз и анализировать ввод (или используйтеfscanf()
, но это будет иметь свои проблемы) - person user3629249   schedule 16.12.2015write(fd2, buffer, sizeof(buffer));
нет гарантии, что массив buffer[] точно заполнен (он может быть меньше, чем полный, или даже переполнен (что приводит к неопределенному поведению). Что действительно необходимо, так это возвращаемое значение изsprintf()
, которое код терпит неудачу сохранить, как длину (3-й) параметр. - person user3629249   schedule 16.12.2015recs->lname, recs->fname
если эти поля не завершены NUL (и дополнены короткими именами) в исходном файле, sprintf() завершится сбоем. - person user3629249   schedule 16.12.2015strncpy
будет заполнять оставшуюся часть буфера нулями до тех пор, пока не будет записаноn
байтов. - person paddy   schedule 17.12.2015strncpy()
NUL дополняет целевую строку. Узнавайте что-то новое каждый день... :) - person Andrew Henle   schedule 17.12.2015recs
и т. д.). Так что вполне возможно, что НИ ОДИН из моих комментариев не является ответом. В таких случаях я очень не решаюсь публиковать такие комментарии в качестве ответа. - person user3629249   schedule 17.12.2015