Проблема заключается в использовании вами fgets()
. Он не возвращает то, что, по вашему мнению, он делает во второй раз.
Первый раз, fgets()
заполняет line[]
"10/23/2014\0"
и все в порядке.
Тем не менее, второй раз до конца, ENTER ключ еще во входном буфере stdin
«s, потому что первый fgets()
не было комнаты в line[]
, чтобы прочитать его, так что второй fgets()
заполняет line[]
с "\n\0"
, не дожидаясь новый пользовательский ввод. Таким образом, первый вызов strtok(line, "/")
возвращает "\n"
(который atoi()
преобразует в 0), затем следующий вызов strtok(NULL, "/")
завершается с ошибкой и возвращает NULL, что вызывает atoi()
для segfault.
Увеличьте размер вашего массива так, чтобы ENTER будет считываться по каждому звонку до fgets()
. Я также предлагаю вам использовать sscanf()
вместо atoi(strtok())
:
const size_t max = 16;
void getDate(Date * d)
{
char line[max];
printf("\t Insert the date in the american format (mm/dd/yyyy): ");
fgets(line, max, stdin);
if (sscanf(line, "%d/%d/%d", &(d->month), &(d->day), &(d->year)) != 3)
d->month = d->day = d->year = 0;
}
Кроме того, добавить некоторые дополнительные проверки, чтобы убедиться, что дата правильно прочитать:
const size_t max = 16;
void getDate(Date * d)
{
char line[max];
int consumed;
printf("\t Insert the date in the american format (mm/dd/yyyy): ");
fgets(line, max, stdin);
while (1)
{
if (sscanf(line, "%d/%d/%d%n", &(d->month), &(d->day), &(d->year), &consumed) == 3)
{
if (consumed == strlen(line))
break;
}
printf("\t Invalid input. Insert the date in the american format (mm/dd/yyyy): ");
fgets(line, max, stdin);
}
}
Segfault - это не утечка памяти! –
Как выглядит ваш вход? –