За пределами неправильной переменной с mktime

Я пытаюсь добавить дату пользовательского ввода в существующую структуру времени, но получаю сообщение об ошибке, которое не понимаю. Компилятор говорит мне, что день недели выходит за рамки, когда я пытаюсь изменить дату месяца. Код размещен ниже.

struct tm date;
int m, d, y, n;
char buffer[80];
printf("Enter a date in mm/dd/yyyy format.\n");
scanf("%d/%d/%d", &m, &d, &y);

date.tm_mday = d;
date.tm_mon = m;
date.tm_year = y - 1900;
mktime(&date);

printf("How many days would you like to advance this time?");
scanf("%d", &n);
date.tm_mday += n;
mktime(&date);
strftime(buffer, sizeof(buffer), "%c", &date);
printf("Your new date is %c", buffer);

person Sam Roehrich    schedule 02.12.2018    source источник
comment
Вы знаете, что диапазон месяцев от 0 до 11, верно? Учитывая, что декабрь - 12-й месяц..   -  person alegria    schedule 03.12.2018
comment
Какие поля есть также в объявленном вами struct tm date;, что вы никогда не удосужились установить какое-либо определенное значение? Некоторые игнорируются mktime; некоторые нет. Ожидаете ли вы, что mktime каким-то образом догадается, что эти значения не были установлены вами до вызова?   -  person WhozCraig    schedule 03.12.2018
comment
Перед началом работы инициализируйте все элементы struct tm в 0: struct tm date = { 0 };. В настоящий момент вы используете неопределенные значения для временных компонентов структуры. Вы также должны проверить, что вызовы scanf() сработали — вернули правильное количество значений (3 и 1 соответственно). Вы можете протестировать вызовы mktime(); вы можете печатать значения date после каждого вызова mktime(). Вы уверены, что компилятор жалуется?   -  person Jonathan Leffler    schedule 03.12.2018


Ответы (1)


Проблемы

  • .tm_mon ожидает месяцы начиная с 0 по 11 января.

    Обычно это означает вычитание 1 из ввода пользователя. @dashboard

    // date.tm_mon = m;
    date.tm_mon = m - 1;
    

  • mktime(&date); читает всех участников, кроме .tm_yday и .tm_wday, а OP устанавливает только 3 из них. Лучше всего инициализировать всех членов с помощью {0}, так как мы знаем только о 7 других, и их может быть больше. @Джонатан Леффлер

  • Код не проверял возвращаемое значение mktime() на наличие ошибок.

  • Используйте "%s", чтобы напечатать строку. Это означает, что у OP нет хорошего компилятора с полностью включенными предупреждениями. Сэкономьте время и включите все предупреждения с помощью хорошего компилятора.

    char buffer[80];
    printf("Your new date is %c", buffer);  // Bad specifier
    

Сложите все это вместе.

// struct tm date;
struct tm date = {0}; // Initialize all
int m, d, y, n;
char buffer[80];

printf("Enter a date in mm/dd/yyyy format.\n");
if (scanf("%d/%d/%d", &m, &d, &y) != 3) {
  Handle_error();  
}


date.tm_mday = d;
// date.tm_mon = m;
date.tm_mon = m - 1;
date.tm_year = y - 1900;
date.tm_isdst = -1; // Set dst flag to: let mktime figure it out
if (mktime(&date) == -1) {
  Handle_error();  
}

printf("How many days would you like to advance this time?");
scanf("%d", &n);
date.tm_mday += n;
if (mktime(&date) == -1) {
  Handle_error();  
}

strftime(buffer, sizeof(buffer), "%c", &date);
printf("Your new date is %s", buffer);
person chux - Reinstate Monica    schedule 02.12.2018