Это связано с спецификатором формата %i
.
Вы не можете наблюдать каких-либо различий в поведении %d
и %i
При использовании с printf()
, но при использовании с scanf
значение очевидно, что %i
принимает целочисленное значение в качестве целочисленного значения с десятичный, шестнадцатеричный или восьмеричный тип, основанный на некотором префиксе, такой, что
если он начинается с 0x
, то он принимает Hex, а перед 0
- как восьмеричное значение. Когда вы используете %d
в scanf
, оно принимает основание 10.
Итак, вам нужно заменить %i
на %d
.
Кроме того, выработайте привычку к чтению справочных страниц из стандартной библиотеки тех функций, которые вы планируете использовать.
Например, scanf
, раздел «Преобразования» гласит, что
я
Соответствует необязательно подписанному целому числу; следующий указатель должен быть указателем на int. Целое число читается в базе 16, если оно начинается с 0x или 0X, в базе 8, если оно начинается с 0, и в базе 10 в противном случае. Используются только символы, соответствующие основанию.
Также в разделе «Возвращаемое значение» , оно гласит,
Возвращаемое значение
Эти функции возвращают количество элементов ввода, успешно сопоставленных и назначенных, которое может быть меньше предусмотренного или даже равно нулю в случае сбоя при раннем сопоставлении.
Значение EOF возвращается, если достигнут конец ввода перед первым успешным преобразованием или ошибкой сопоставления. EOF также возвращается, если происходит ошибка чтения, и в этом случае устанавливается индикатор ошибки для потока (см. Ferror (3)), и устанавливается errno, обозначающий ошибку.
Получение возвращаемых значений из scanf
и добавление некоторой обработки ошибок для неожиданного возврата избавят вас от многих проблем в будущем.
Дополнительные входы:
- Обычно предпочитают / рекомендуют называть вашу функцию глаголом (или действием), а не тем, что не имеет смысла.
Например,
int valueofN (struct date d);
int f(int year, int month);
int g(int month);
Если я проверяю ваш код, я не знаю, что делает эта функция. В дальнейшем назовите функции и другие переменные так, чтобы это имело смысл.
- Использовать совместимые типы данных
Например,
long int N1 = valueofN (date1);
long int N2 = valueofN (date2);
N1
и N2
относятся к типу данных long int
, а valueofN()
возвращает int
. Это другой тип данных, в этом коде нет непосредственного вреда, но в этой практике есть потенциальный вред.
- Некоторое улучшение
Это
int valueofN (struct date d)
{
int N;
return N = (1461 * (f(d.year, d.month) / 4) + 153 * (g(d.month) / 5)+ d.day);
}
могло бы быть
int valueofN (struct date d)
{
return (int)(1461 * (f(d.year, d.month) / 4) + 153 * (g(d.month) / 5) +d.day);
}
- Еще одно улучшение: вы всегда должны проверять данные, введенные пользователем (если вы не знаете нижнюю и верхнюю граничные значения). Например, пользователь может ввести
50
для month
. Это не подтверждено. Обработайте это на самом этапе ввода. Сделайте это привычкой.