ScanF в то время как цикл - PullRequest
       47

ScanF в то время как цикл

2 голосов
/ 20 февраля 2010

В этом коде scanf работает только один раз. Что я делаю не так?

#include <stdio.h>
#include <unistd.h>

int main()
{
    int i = 1;
    if (! fork())
    {
        while(i)
        {
            printf("Enter i");
            scanf("%d", &i);
            fflush(stdin);
            fflush(stdout);
        }
    }
    else
    {
        printf("Parent\n");
    }
    return(0);
}

Ответы [ 5 ]

3 голосов
/ 21 февраля 2010

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

Также было отмечено, что вы не должны сбрасывать stdin через fflush, поскольку это вызывает неопределенное поведение. Если вы чувствуете, что должны сбросить stdin, вы можете обратиться к ответам на на этот вопрос .

Если введено недопустимое значение, например "1,234" , scanf примет '1' и ", 234 / n" останется во входном потоке. Поскольку fflush(stdin) не гарантированно работает, последующие вызовы на scanf будут снова и снова отклонять одни и те же ',' , никогда не делая никакого прогресса. Если возвращаемое значение проверяется на ноль (что указывает на раннее совпадение), этого бесконечного цикла можно избежать. Также необходимо удалить недопустимые символы из входного потока перед другим вызовом scanf.


См. scanf (), вызывающий бесконечный цикл .

1 голос
/ 21 февраля 2010

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

Чтобы сохранить доступ ребенка к стандартному вводу-выводу, вам нужно остановить родителя до его завершения. Используйте wait или связанную функцию.

#include <sys/wait.h>

...

else {
    printf( "parent\n" );
    wait( NULL );
}

Это исправляет вашу ошибку на моей машине. Я не эксперт по семантике файловых дескрипторов Unix, но кажется, что получающаяся программа может быть переносимой. Почему вы хотите сделать это другое дело ...

1 голос
/ 21 февраля 2010

Трудно сказать, не видя, какой вклад вы предоставляете. Если он работает без fork, то это может быть конфликтом, как описано Амитом. Две другие вещи, однако:

  1. Не использовать scanf.

  2. fflush(stdin) - это неопределенное поведение . Не делай этого.

Из comp.lang.c FAQ:

1 голос
/ 20 февраля 2010

попробуйте проверить, если я> 0.

0 голосов
/ 20 февраля 2010

Сначала я попытался извлечь самый простой код, который дает проблему (долгое время не использовал C / scanf). Код без fork работает нормально. Небольшой поиск в Google "fork scanf" дал мне ответ .

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

#include<stdio.h>
#include<unistd.h>
int main()
{
        int i = 1;
        if(!fork())
        {
                while(i)
                {
                        printf("Enter i");
                        int j = scanf("%d",&i); // changed
                        if(j == EOF) {             // added
                                printf("stream closed"); // added
                                return 1;       // added
                        }                       // added
                        fflush(stdin);
                        fflush(stdout);
                }
        }
        else
        {
                printf("Parent\n");
        }
        return(0);
}
...