Проблема при сканировании полукокса и поплавка одновременно - PullRequest
0 голосов
/ 25 сентября 2010

Я пытаюсь ввести пять символов и 5 чисел с плавающей запятой.

main()  
{    
char c[5];    
float q[5];    
int i;

for(i=0;i<5;i++)  
{   
        printf("\n%d ",i);  
    scanf("%c",c+i);   
    scanf("%f",q+i);  
    }  
}

Но вывод абсурден. После двух последовательных сканирований оно пропускает третье сканирование, а затем снова пропускает пятое сканирование. Я не могу понять, почему это показывает такое поведение. Я работаю над компилятором gcc.

Ответы [ 6 ]

2 голосов
/ 25 сентября 2010

Чтобы прямо ответить, почему 3-й и все остальные сканы «пропускаются», так работает формат scanf() и %c.Когда есть звонок на scanf(), вам обычно нужно нажать ввод, чтобы «отправить» ввод.Следовательно, это вставляет символ новой строки в поток stdin.

Когда было введено предыдущее сканирование с плавающей запятой, новая строка все еще остается в потоке.Когда сканирование символа достигнуто, этот оставшийся символ новой строки считывается, поскольку он эффективно «пропускает» вызов.

Вы должны использовать fgets() с sscanf(), как подсказывает кодаддикт.

Но для быстрого исправления вы можете попробовать добавить вызов к getchar() после сканирования с плавающей запятой, чтобы использовать этот символ новой строки из потока.

edit:
Вы говорите, что это не работает?(при условии, что вы вводите правильные виды значений, по одному на каждый вызов scanf)

main()
{
    char c[5];
    float q[5];
    int i;

    for(i=0;i<5;i++)
    {
        printf("\n%d ",i);
        scanf("%c",c+i);
        scanf("%f",q+i);
        getchar();
    }
}
2 голосов
/ 25 сентября 2010

Использование scanf не рекомендуется из-за подобных проблем.

Вместо этого используйте fgets, чтобы прочитать всю строку, а затем используйте sscanf, чтобы извлечь то, что вы хотите (char или float) из строки, только что прочитанной:

    char line[MAX];
    for(i=0;i<5;i++)
    {
            if( fgets(line,MAX,stdin) && sscanf(line,"%c", c+i)!=1 )
                    *(c+i) = 0;
            if( fgets(line,MAX,stdin) && sscanf(line,"%f", q+i)!=1 )
                    *(q+i) = 0.0;
            printf("%c %f\n",*(c+i),*(q+i));

    }
1 голос
/ 31 января 2013

Вы должны попробовать это:

    int main(){
    char c[6];//char array size must be 6 to store five charecter
              //as null-terminator('\0')will use the last one
    float q[5];
    int i;
    for(i=0;i<5;i++){
            printf("\n%d\n",i);fflush(stdout);
            scanf("%c",&c[i]);fflush(stdin);//fflush(stdin) to clear input stream that
                                            //next scanf() won't skip
            scanf("%f",&q[i]);fflush(stdin);//fflush(stdin) to clear input stream that
                                            //scanf() won't skip at new loop
    }
    return 0;
    }
0 голосов
/ 13 июня 2011

Проблема в сканировании значения символа после значения с плавающей запятой.

Решение очень простое *

вместо написания вашего кода, как это

scanf("%c",&...)

попробуйте это,

scanf(" %c",&...)

Пробел перед "% c" решит проблему, пренебрегая значением клавиши Return (Enter) при нажатии после ввода значения с плавающей запятой в качестве ввода.

Когда значение с плавающей запятой сканируется перед символьным значением. Значение, полученное нажатием клавиши Return (Enter), собирается в следующую переменную char. Использование пробела перед ("% c", & ...) отбрасывает значение, полученное клавишей Return (Enter), вызывая сканирование значения Char в следующей строке. Таким образом, решая Сканирующую задачу типа Float-Char.

0 голосов
/ 25 сентября 2010

Ваш код должен быть таким:

main()  
{    
char c[5];    
float q[5];    
int i;

for(i=0;i<5;i++)  
{   
        printf("\n%d ",i);  
    scanf("%c",c+i);
    while (getchar()!='\n');   
    scanf("%f",q+i);
    while (getchar()!='\n');   
    }  
}

предложение while (getchar()!='\n'); поиск до конца ввода, поэтому он не будет принимать '\ n' в качестве значения ввода для q + i.Alsoеще один while (getchar()!='\n'); после scanf q + i, так как вы используете loop.

0 голосов
/ 25 сентября 2010

fflush() не определено во входном потоке, как stdin.Не делайте этого.

Если вы хотите «прочитать и выбросить до новой строки», то выполните:

int ch;
do {
    ch = getchar();
} while (ch != EOF && ch != '\n');

Обратите внимание, что %c означает «прочитать следующий символ на входепоток, даже если это пробел, тогда остановитесь ".%f означает «читать и отбрасывать пробелы, затем пытаться читать число с плавающей точкой из входного потока, а затем останавливаться».

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