Ошибка SIGSEGV 11 при записи структуры в файл
Пытаюсь записать структуру в файл в бинарном виде, но постоянно выпадает ошибка SIGSEGV 11. не понимаю в чём проблема. Точнее, побочный эффект проявляется, когда записываю строки, в основном. Пытался понять что не так через gdb, но не помогает.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "student.h"
int read_student(student* st) {
return scanf("%s,%c,%c,%s,%s\n",
st->name, &st->sex, &st->class, st->university, st->job) == 5;
}
int main(int argc, char* argv[]){
student* st = malloc(sizeof(student)); student* prev = malloc(sizeof(student));
FILE* out = fopen(argv[1], "wb");
while (read_student(st)) {
printf("%s -> ", st->name);
if (strcmp(st->name, prev->name))
break;
*prev = *st;
fwrite(&st, sizeof(st), 1, out);
printf("success\n");
}
fclose(out);
return 0;
}
Заголовочный файл student.h:
#ifndef __applicant_h__
#define __applicant_h__
typedef struct {
char name[50]; // фамилия и инициалы
char sex; // пол
char class; // буква класса
char university[50]; // университет
char job[30]; // место работы
} student;
#endif
Запускаю в терминале так: (./student.o data.bin) < data.txt
Тестовые данные выглядят так (data.txt):
Artyom A.C.,m,A,Moscow Aviation Institute,Mobile TeleSystem
Maria S.K.,f,B,Moscow State University,Unemployed
Что я делаю не так?
Ответы (1 шт):
Много, слишком много несуразиц.
Ну, пусть вы не забыли передать имя файла и таки открыли его (вы не проверяете, ни передано ли его имя, ни открылся ли он).
Но дальше при чтении с помощью %s вы читаете одно слово, за которым нет запятой, и благополучно выходите из цикла - scanf возвращает не 5, а 1. Кстати, кто мешал вам вывести хотя бы отладочную запись и посмотреть, что же происходит на самом деле?
Дальше - когда вы исправите, например, как scanf("%[^,],%c,%c,%[^,],%[^\n]", вы пытаетесь использовать неинициализированную память prev. Не то чтоб в данном случае это было сильно страшно, но очень нехорошо. Особенно в других случаях, где это важно.
Вы сравниваете strcmp(st->name, prev->name), а поскольку там мусор (в prev->name), можно спорить, что строки не равны, а значит, функция strcmp вернет не ноль, и вы вылетаете из цикла...
Но даже если вы исправите и это, то потом вы записываете в файл значение указателя, а не того, на что указатель указывает. Вам точно нужно именно это?
По-моему, вы хотели
fwrite(st, sizeof(student), 1, out);
[Грустно] Скажите после этого - а что вы делаете "так"?... И, кстати, нигде ни одну ошибку не проверяете (ну, попытались только со scanf)...