Есть ли проблемы с моим использованием функции printf? - PullRequest
1 голос
/ 25 марта 2019

Мне было дано следующее задание для выполнения в C: -

Год делится на четыре сезона: весна, лето, осень и зима.Хотя точные даты смены сезонов меняются от года к году в зависимости от способа составления календаря, мы будем использовать следующие даты для этого упражнения:

Первый сезонденьЛето 20 мартаВесна 21 июняОсень 22 сентябряЗима 21 декабря

Создайте программу, которая читает месяц и день от пользователя.Пользователь введет название месяца в виде строки, а затем день в месяце в виде целого числа.

Затем ваша программа должна отобразить сезон, связанный с введенной датой..

Примечание: введите первые три буквы для примера месяца: январь для января, февраль для февраля и т. Д. .... и первая буква месяца должна быть заглавной.

Я написал мини-тестовый код для проверки первого условия, то есть 20 марта.

Вот мой код: -

#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[]) {
int date;
char month[3];

printf("Enter the month\n");
scanf("%s",month);

printf("Enter the date\n");
scanf("%d",&date);

int temp;
temp= strcmp(month,"Mar");
printf("output is %d\n",temp);
return 0;
}

Проблема, которую я получаю, заключается в том, что при вводе данных как Mar и 20 , я получаю вывод: - "output is 20" .Принимая во внимание, что я предполагаю получить вывод как 0 в моем тестовом коде.

Еще одно наблюдение состоит в том, что, если я изменяю дату на любое случайное число, я получаю это как вывод, тогда как я предполагаю получитьзначение, которое хранится в Temp, т. е. 0.

Я получаю правильный вывод, если полностью удаляю переменную date из кода.В это время я получаю 0.

Ответы [ 2 ]

4 голосов
/ 25 марта 2019

Использование вашей функции printf правильное, вы печатаете целое число, используя правильный спецификатор преобразования для него "% d", как описано в https://linux.die.net/man/3/printf

Что может не быть в порядке - это переменная 'month'. Это буфер символов с 3 байтами для хранения. Вы используете его для хранения строк с нулевым символом в конце, поэтому он может хранить только 2 символа ASCII + нулевой терминатор.

Другая проблема заключается в том, как функция scanf используется для получения строки месяца. Если вы не укажете ширину поля, все может выглядеть ужасно, для получения дополнительной информации см. https://linux.die.net/man/3/scanf.

0 голосов
/ 25 марта 2019

Помните, что строки C включают в себя терминатор с 0 значениями, поэтому для хранения строки из N символов вам понадобится массив символов шириной не менее N + 1 элементов.

Функции управления строками, такие как strcmp, полагаются на этот терминатор, чтобы сообщить им, где находится конец строки.Вероятная причина, по которой вы получаете странный вывод, состоит в том, что строковая константа "Mar" заканчивается 0, а строка, хранящаяся в вашем массиве month, отсутствует, поэтому strcmp читает после конца массива monthпока он не увидит 0-значный байт и не вернет разницу между "Mar" и "Mar<em>x</em>", где x представляет некоторую неизвестную последовательность байтов.

Доступ к памяти после конца массива приводит к неопределенному поведению , и любой результат возможен.

Чтобы устранить эту конкретную проблему, объявите month как массив из 4 элементов char и ограничьте ввод до 3 символов при вызове scanf:

char month[4];
...
scanf( "%3s", month );

стандартная подпись main:

int main( void )

или

int main( int argc, char *argv[] ); // NOT const

Массив argv должен быть изменяемым:

5.1.2.2.1 Запуск программы
...
- параметры argc и argv и строки, на которые указывает argv* Массив 1047 * должен изменяться программой и сохранять свои последние сохраненные значения между запуском программы и завершением программы.

C 2011 Онлайн-черновик

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...