Re[5]: Использование printf() и scanf()
От: Eugenio Россия  
Дата: 14.06.05 04:09
Оценка:
Здравствуйте, ansi, Вы писали:

A>Здравствуйте, <Аноним>, Вы писали:


А>>Тогда вопрос. Если в буфере, после ввода 'y' (спецификатор "%c") остается символ '\0' — не понимаю, как тогда вообще считать только один символ?


A>Он там не останется. Сивол '\0' записывается в конец строки, но не является частью буфера. Ты же спецификатором "%[NnYy]" указывал, что тебе надо считать именно строку и давал указатель char *, который вмещал в себя один символ, но scanf'у то пофиг, что ты не позаботился о выделении достаточного количества памяти. Если ты вызовешь с "%c", то scanf запишет ровно один символ.


Да, но прога-то, КОГДА ВВОДИТСЯ С КЛАВИАТУРЫ 1 (ОДИН) СИМВОЛ, ведет себя так, как она по вашим словам должна себя вести, когда их там больше (и все, что сверх "моего" char, остается в буфере) — она больше не ждет ничего от юзера,
она сразу приступает к проверке второго символа, он не подходит, и прога завершается!
Re[6]: Использование printf() и scanf()
От: ansi  
Дата: 14.06.05 05:51
Оценка:
Здравствуйте, Eugenio, Вы писали:

E>Да, но прога-то, КОГДА ВВОДИТСЯ С КЛАВИАТУРЫ 1 (ОДИН) СИМВОЛ, ведет себя так, как она по вашим словам должна себя вести, когда их там больше (и все, что сверх "моего" char, остается в буфере) — она больше не ждет ничего от юзера,

E>она сразу приступает к проверке второго символа, он не подходит, и прога завершается!
Я тебя не совсем понял, точнее совсем не понял ... Давай исправленный код, а там глянем.
Re[7]: Использование printf() и scanf()
От: Eugenio Россия  
Дата: 14.06.05 07:59
Оценка:
Здравствуйте, ansi, Вы писали:

A>Я тебя не совсем понял, точнее совсем не понял ... Давай исправленный код, а там глянем.

В коде ничего не исправлял, т.к. вопрос не в новом коде — а полученные прежде объяснения не все объясняют.
Я имею ввиду, что после первого вызова scanf("%[NnYy]",) и ввода юзером 1 (одного) символа,
повторный вызов scanf с теми же параметрами не работает:
программа проходит этот кусок и завершается, не принимая ввода от юзера.
Это может объясняться наличием в буфере еще не считанных символов, но их там НЕТ!
Re: использование scanf()
От: Linuxoid  
Дата: 14.06.05 08:10
Оценка: +1
Первый совет по использованию функции scanf() — никогда не используй функцию scanf(). Как говорил мой препод по информатике — scanf — функция для дураков. Ее можно использовать когда ты читаешь входные данные, которые выдает тебе другая программа (и которые имеют четко оговоренный заранее известный формат), а с таким ненадежным источником данных, как человек, использование scanf() ни к чему хорошему не приведет. Можно использовать такой ввод данных разве что в учебном примере. Вместо scanf рекомендую выполнять посимвольный ввод с последующим парсингом.
Re[8]: Использование printf() и scanf()
От: ansi  
Дата: 14.06.05 08:56
Оценка:
Здравствуйте, Eugenio, Вы писали:

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


A>>Я тебя не совсем понял, точнее совсем не понял ... Давай исправленный код, а там глянем.

E>В коде ничего не исправлял, т.к. вопрос не в новом коде — а полученные прежде объяснения не все объясняют.
E>Я имею ввиду, что после первого вызова scanf("%[NnYy]",) и ввода юзером 1 (одного) символа,
E>повторный вызов scanf с теми же параметрами не работает:
E>программа проходит этот кусок и завершается, не принимая ввода от юзера.
E>Это может объясняться наличием в буфере еще не считанных символов, но их там НЕТ!

Ясно, что ничего не ясно.
Во-первых, в твоей программе вызов scanf("%[NnYy]", &inp) только один. После него идет scanf("%f", ...).
Во-вторых, чего ты собственно хочешь, если ты портишь стек? Чисто ради спортивного интереса, попробуй вместо
char inp;


Написать
char _buff[20];
char &inp = _buff[0];

должно заработать... Если не заработает, то покажи, что именно ты запускаешь.

В-третьих, я пробовал на VS 2003 и все работает и в дебаг версии, и в релизной. ВС++ 3.1 тоже съел на ура. Ну то есть, если ты херишь стек, то вообще-то хорошо, что она у тебя не работает, иначе эту ошибку можно было бы не отловить... В общем какой компилятор?
Запускаю это:

int _tmain(int argc, _TCHAR* argv[])
{
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);

    switch (inp)
    {
        case 'y':
        case 'Y':
            printf("Input number of feet:\n");
            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): ");
                scanf("%f", &feet);
            }
            return 0;
    }



   return 0;
}
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "Ice MC — Run fa cover";
Re[9]: Использование printf() и scanf()
От: Eugenio Россия  
Дата: 14.06.05 13:06
Оценка:
E>>Я имею ввиду, что после первого вызова scanf("%[NnYy]",) и ввода юзером 1 (одного) символа,
E>>повторный вызов scanf с теми же параметрами не работает:
E>>программа проходит этот кусок и завершается, не принимая ввода от юзера.
E>>Это может объясняться наличием в буфере еще не считанных символов, но их там НЕТ!

A>Во-первых, в твоей программе вызов scanf("%[NnYy]", &inp) только один. После него идет scanf("%f", ...).


См. в конце этого куска кода — очередной вопрос (printf) и вызов scanf с теми же параметрами, что и в первый раз.
Если ввести 'n' в первый раз, то вызова scanf("%f", ..) не последует, так? Так.
И управление сразу передастся туда, где задается второй вопрос.
Так вот, второй вопрос прога задает, но ввода прога не ждет. Не могу понять, какого..? В рабочей-то проге я уже сделал всё (getchar()), но я не понимаю, что ЗДЕСЬ не так!
Re[10]: Использование printf() и scanf()
От: ansi  
Дата: 15.06.05 12:36
Оценка:
Здравствуйте, Eugenio, Вы писали:

E>>>Я имею ввиду, что после первого вызова scanf("%[NnYy]",) и ввода юзером 1 (одного) символа,

E>>>повторный вызов scanf с теми же параметрами не работает:
E>>>программа проходит этот кусок и завершается, не принимая ввода от юзера.
E>>>Это может объясняться наличием в буфере еще не считанных символов, но их там НЕТ!

A>>Во-первых, в твоей программе вызов scanf("%[NnYy]", &inp) только один. После него идет scanf("%f", ...).


E>См. в конце этого куска кода — очередной вопрос (printf) и вызов scanf с теми же параметрами, что и в первый раз.

E>Если ввести 'n' в первый раз, то вызова scanf("%f", ..) не последует, так? Так.
E>И управление сразу передастся туда, где задается второй вопрос.
E>Так вот, второй вопрос прога задает, но ввода прога не ждет. Не могу понять, какого..? В рабочей-то проге я уже сделал всё (getchar()), но я не понимаю, что ЗДЕСЬ не так!

Теперь понятно:
scanf("%c", &c);
scanf("%c", &c);


После ввода 'y' + Enter, c будет содержать символ перевода строки (10)... scanf — это чудо Кстати, getchar — это те же яйца, только в профиль. Вот функция _getche реально с консоли читает один символ, но это приблуда микрософта. Есть еще одна приблуда микрософта — _flushall. Если будешь вызывать после каждого scanf, то она будет чистить внутренний буфер и проблем не будет.

Короче, если есть возможность — используй заплюсованные потоки, они слава богу продуманы получше.

Если нет возможности, то можно сделать такие хитрожопые обертки:

char my_read_char() {

   char buff[3];

   fgets(buff, 2, stdin);
   return buff[0];

}



#define MAX_FLOAT_STRLEN 15

int my_read_float(float *f) {

   char buff[MAX_FLOAT_STRLEN];
     
   fgets(buff, MAX_FLOAT_STRLEN - 1, stdin);
   return sscanf(buff, "%f", f);
}
new RSDN@Home(1.1.4, 303) << new Message(); std::head::ear << "Apocalyptica — Nothing Else Matters";
Re[11]: Использование printf() и scanf()
От: Eugenio Россия  
Дата: 20.06.05 05:31
Оценка:
Здравствуйте, ansi, Вы писали:

A>Теперь понятно:

A>
A>scanf("%c", &c);
A>scanf("%c", &c);
A>


A>После ввода 'y' + Enter, c будет содержать символ перевода строки (10)... scanf — это чудо Кстати, getchar — это те же яйца, только в профиль. Вот функция _getche реально с консоли читает один символ, но это приблуда микрософта. Есть еще одна приблуда микрософта — _flushall. Если будешь вызывать после каждого scanf, то она будет чистить внутренний буфер и проблем не будет.


A>Короче, если есть возможность — используй заплюсованные потоки, они слава богу продуманы получше.


Спасибо, ansi. Пусть будут "заплюсованные".
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.