Re[2]: Использование printf() и scanf()
От: ansi  
Дата: 13.06.05 07:57
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, LaptevVV, Вы писали:


А>Добрый день.

А>Столкнулся с такой проблемой (со scanf):
А>после первого использования не могу больше считать
А>ничего! Вот иллюстрация, специально набросал:

Вообще, в дебаге она работает. А так смотри ниже...

А>
А>    float feet, meters, centimeters;
А>    float foperand1 = 0, foperand2 = 0;
А>    char inp;
А>    printf("Hello, world!\n");
    
А>    printf("Do you want to transfer some feet to meters? (y/n): ");

Ошибка номер раз:
А>    scanf("%[nNyY]c", &inp);
Набор символов в вквадратных скобках есть указание читать строку. 
Соответственно, если я введу y, то получим {'y', '\0'} - похерили стек.
Поэтому надо просто вызвать getchar.

А>    switch (inp)
А>    {
А>        case 'y':
А>        case 'Y':
А>            printf("Input number of feet:\n");

Ошибка 2: 
А>            scanf("%f", &feet);
Если я введу какой-нибудь буквенный символ, то прога твоя зациклится.
            
А>            while (feet)
А>            {
А>                centimeters = feet * 12 * 2.54;
А>                meters = centimeters / 100;
А>                printf("%8.2f (feet) is equal to\n", feet);
А>                printf("meters %8.2f \n", meters);
А>                printf("centimeters %8.2f \n", centimeters);
А>                printf("\nInput another value in feet (0 - exit program): ");

Ошибка 3: см. 2
А>                scanf("%f", &feet);
А>            }
А>            SayGoodBye();
А>            return 0;
А>    }

А>    printf("Do you want to see the results of C++ operators? (y/n): ");
А>    scanf("%[nNyY]c", &inp);

А>    switch (inp)
А>        .......
А>


А>Так вот, попытка снова считать что-то в переменную inp после второго вопроса — не выполняется: программа просто завершается ("с кодом 0").

А>Что тут не так?
Вообще, как работает scanf: с клавиатуры читается буфер, далее из этого буфера читается значение пока:
Позиция в буфере запоминается и равна последнему считанному символу.

Например, если ты вызвал scanf("%c"), а я ввел "yes", то scanf запишет в буфер "yes". Далее в твою переменную он запишет символ 'y'. Буфер теперь содержит "es".

Далее, при следующем вызове scanf она смотрит, есть ли у нее что-нибудь в буфере, и если есть, то ввод с клавиатуры не производится, а очередной токен читается из этого буфера.
В нашем случае буфер содержит "es". И если ты сейчас вызовешь scanf("%f"), то на первом же символе 'e' функция заматерится и вернет управление, в твоей же переменной останется какой-то мусор (скорее всего не нулевой) а буфер останется таким же. Это причина ошибок 2 и 3.

Еще один пример:
int array[10];

for (int i=0; i<10; ++i)
    scanf("%d", &array[i]);


Если в этом примере ввести "1 2 3 4 5 6 7 8 9 0", то получится, что ты считаешь все 10 элементов за один раз (пробелы scanf просто игнорирует), хотя вызов scanf стоит в цикле

Что тебе надо сделать:
1) Вызывать getchar. Хотя в принципе можно и scanf("%c"), или scanf("%s"). Для последнего нужен массив, а про первый я уже говорил.
2, 3) Проверять значение, возвращенное функцией scanf (она возвращает число корректно считанных токенов). Если вернула 0, то тебе подсунули что-то нехорошее.
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "Ice MC — Easy";
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.