Member 13379994 Ответов: 2

Как я могу заставить функцию scanf работать в этом случае?


<pre>
/*
This project displays number of days in a month

Assumption:- February is assumed to have 28 days
             All other months have 30 or 31 days
*/

#include <stdio.h>
#include <stdlib.h>

int main()

{
    int month_value;
    char user_choice='y';

    while(user_choice=='y'||user_choice=='Y')
    {
        system("cls");
        printf("Enter the serial number of month:- ");
        scanf("%d",&month_value);
        if(month_value>=1&&month_value<=12)
        {
            if(month_value%2!=0)
            {
                printf("The number of days in this month is:- 31\nDo you want to check for another month?(y/n)\n");
                scanf("%c",&user_choice);  // this statement is not getting executed even if condition is true

            }
            else if(month_value%2==0 && month_value!=2)
            {
                printf("The number of days in this month is:- 30\nDo you want to check for another month?(y/n)\n");
                scanf("%c",&user_choice);   // this statement is not getting executed even if condition is true
            }
            else
            {
                printf("The number of days in this month is:- 28\nDo you want to check for another month?(y/n)\n");
                scanf("%c",&user_choice);   // this statement is not getting executed even if condition is true
            }

        }
        else
        {
            printf("ERROR\nWould you like to re-enter the value?(y/n)\n");
	        scanf("%c",&user_choice);   // this statement is not getting executed even if condition is true
        }
    }
    return 0;
}


Что я уже пробовал:

Я потратил 4-5 часов, просто думая, какая логическая ошибка может присутствовать, но я не мог понять ее. Пожалуйста помочь.На мой взгляд, это должно сработать.

2 Ответов

Рейтинг:
1

OriginalGriff

Хм. Посмотрите на количество дней в каждом месяце. Следует ли это абсолютно регулярному образцу?

Month :  J  F  M  A  M  J  J  A  S  O  N  D
Number:  1  2  3  4  5  6  7  8  9 10 11 12
Days  : 31 28 31 30 31 30 31 31 30 31 30 31
То есть все ли четные месяцы имеют 30 дней?



Так почему же вы предполагаете (за исключением особого случая для февраля), что они это делают?


[редактировать]
Цитата:
Поэтому напишите функцию, которая принимает приглашение и получает ответ.

Ты знаешь, как это делается! Это функция, которая возвращает значение yes / no (в языке C это int, а 0-это true / yes а любая другая ценность-это false / no) и это принимает строку, которая является char указатель:
#define true (1==1)
#define false (1==1)
...
int YesOrNo(const char* prompt)
   {
   ...
   }
То const означает "это не может быть изменено внутри функции" - если вы еще не рассмотрели это, не беспокойтесь об этом
Внутри функции распечатайте строку и получите ответ пользователя в виде строки - вы знаете, как это сделать!
Посмотрите на символы в строке, которые вы получаете обратно, и решите, набираете ли вы "y" или "n". Если да, то возвращайтесь true или false.
Если нет, продолжайте читать, пока он этого не сделает.
Ты знаешь, как это делается, если хорошенько подумать!
[/редактировать]


Member 13379994

спасибо, я этого не заметил. Хорошо, я сделаю необходимые изменения. В этом случае предположим, что пользователь вводит число, меньшее, чем равное 7. Тогда scanf должен работать, но это не так, почему?

OriginalGriff

что именно вы подразумеваете под "не работает"?
Что он делает такого, чего вы не ожидали, или не делает того, что вы сделали?
И какой именно? У вас их несколько...

Member 13379994

Я ожидаю, что строка scanf("%c",&user_choice) будет работать там, где она присутствует в коде. Перед этой строкой scanf в каждом случае if else/else я спрашиваю пользователя, хочет ли он знать количество дней для других месяцев или нет. Пользователь должен ввести "y" или "Y", чтобы проверить больше месяцев, и "n", чтобы выйти из цикла while. Я выполнил этот код в codeblocks, но обнаружил, что оператор scanf("%c",&user_choice) не работает. Таким образом, пользователь не мог вводить свой выбор снова и снова. Программа просто спрашивает:" Вы хотите проверить другие месяцы?", и она существует в программе перед выполнением оператора scanf ("%c",&user_choice). Извините за мой бедный английский.

OriginalGriff

Скорее всего, это *работает* - просто новая строка из предыдущей записи все еще находится в системе и читается как ответ символа.
Попробуйте провести эксперимент: поместите scanf в функцию и повторите полученное шестнадцатеричное значение до тех пор, пока не получите буквенный символ.

Или попробуйте отладчик - я держу пари, что user_choice сразу же удерживает #0A или #0D.

Member 13379994

Я попробовал отладить. Я установил точку останова в строке "char user_choice= 'y' " и начал отладку оттуда. Я ввел 3 как month_value.

До строки " printf ("количество дней в этом месяце равно: - 31\nDo вы хотите проверить еще один месяц? (y/n)\n");"

user_choice имел значение "y", но сразу после этой строки значение user_choice стало "\n". В то время как цикл был нарушен оттуда, и программа была прекращена.

Хм, что я могу сделать, чтобы узнать, почему user_choice содержит значение '\n' или как я могу сделать переменную user_choice не содержащей значения '\n'.

OriginalGriff

Вот что я говорил - Если вы помните свой printf, '\n ' - это символ новой строки.
Когда вы вводили цифру "3", вы нажимали две клавиши: цифру 3 и ENTER, которые помещали два символа во входную очередь. Scanf удалил все числовые символы, чтобы вернуть целое число, но остановился, когда нашел нечисловое. Этот символ был оставлен во входном потоке для последующего процесса, поэтому, когда вы в следующий раз вызвали scanf для чтения символа, он вернул '\n' - новую строку, которой вы завершили "3".

Именно такого поведения я и ожидаю, и ты тоже, если хорошенько подумать!
Поэтому напишите функцию, которая принимает приглашение и получает ответ. Не сканируйте символ, сканируйте строку и проверьте это на "y\n "и" n\n", прежде чем возвращать логическое значение "Да / нет". Игнорируйте пустые строки.
Красиво и просто!

Member 13379994

Пожалуйста, объясните более подробно второй абзац вашего ответа. Раздавая подсказки, как написать эту функцию.Как проверить против... Я боюсь, прочитал ли я полную теорию или нет (за то, что вы просите меня сделать). Это кажется очень интересным. Я хочу учиться, но подумайте, что я начал C неделю назад. Пожалуйста, объясните еще немного. Я научился отладке на youtube. Это было что-то новое для меня :p, но я сделал. спасибо за это :D

OriginalGriff

Ответ обновлен.

Member 13379994

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

OriginalGriff

Нет! :смеяться:
Это твое домашнее задание, и ты должен сдавать свою работу, а не мою. Помните, что ваш наставник знает, что такие сайты существуют...

Давай, попробуй. У вас есть функция " shell "в ответе выше, поэтому добавьте к ней код, чтобы напечатать приглашение и вернуть" true " на данный момент, а затем протестируйте его.
Когда ты это поймешь, мы двинемся дальше.

Member 13379994

Хорошо, тогда я дам себе немного времени.

OriginalGriff

:большой палец вверх:
Вы учитесь гораздо лучше, делая, чем читая!

Рейтинг:
0

Patrice T

Существует инструмент, который позволяет вам видеть, что делает ваш код, его имя отладчик Это также отличный инструмент обучения, потому что он показывает вам реальность, и вы можете увидеть, какие ожидания соответствуют реальности.
Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик-Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010-YouTube[^]
Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.

[Обновление]
Прежде всего, убедитесь, что то, что вы думаете, соответствует действительности.
Попробуй

printf("The number of days in this month is:- 31\nDo you want to check for another month?(y/n)\n");
scanf("%c",&user_choice);  // this statement is not getting executed even if condition is true
printf("The number of days in this month is:- 31\nDo you want to check for another month?(y/n)\n");

Если вы получите отпечаток один раз, выполнение остановится между ними.
Если вы получаете печать дважды, сканирование выполняется, но не дает ожидаемого результата. Используйте отладчик для проверки значения переменной после сканирования.
Цитата:
это утверждение не выполняется, даже если условие истинно

Оператор может быть выполнен только в том случае, если условие истинно.


Member 13379994

Я использую кодовые блоки. Я немного узнал об отладке с youtube. Научился видеть значения переменной в каждой точке. Так что я думаю, что с обучением отладке покончено. С помощью отладчика я узнал, где мой код идет не так, но так как моя теория не завершена, мне нужно сидеть и читать, а затем думать о решении. Если вы хотите, вы можете увидеть другой ответ OriginalGriff и наш чат в комментариях, чтобы узнать, что мы разработали до сих пор :) Мы близки к решению этой проблемы, но мне нужно учиться.

Patrice T

Вы должны обновить свой вопрос со всеми деталями, которые вы разработали.
Обычно мы не обращаем особого внимания на дискуссии.
Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.