Как именно космос работает с scanf? - PullRequest
4 голосов
/ 22 января 2012

Я учусь на математике и изучаю основы программирования на C. Мне нужна программа для чтения входных данных, состоящих из массива, компоненты которого должны иметь определенные реквизиты;Я хотел бы, чтобы программа спросила пользователя о компонентах массива.Пользователь должен затем ввести такие компоненты, разделяя их пробелами.Детали не важны, чтобы объяснить главный вопрос;Я выберу более простой пример, чем тот, с которым я имею дело: допустим, я хочу, чтобы массив из 6 компонентов не содержал число 4. Поэтому я попытался:

#include <stdio.h>

int main(void) {
    int a[6];
    printf("enter components: ");
    int i;
    for (i = 0; i < 6; i++) {
        scanf("%d", &a[i]);
        if (a[i] == 4) printf(" \n\n4 is not allowed, try again\n\n");
    }
    for (i = 0; i < 6; i++) {
        printf("%d ", a[i]);
    }
}

Если я скомпилирую это и выполнюнапример, введите:

1 2 3 4 5 6

Я получу сообщение об ошибке, но только после нажатия клавиши ввода, то есть после ввода всех шести компонентов (не сразу после нажатия пробела в четвертый раз),Итак, вот мои вопросы (я ищу решений, в которых не используются строки или указатели , если без них невозможно обойтись):

  1. Есть ли способ заставить программу читать компонент (и действовать соответственно) сразу после ввода его следующего пространства?Я предполагаю, что нет, потому что scanf работает только после того, как пользователь нажимает ввод, а не пробел, правильно?

  2. Если нет, есть ли способ получить программучитать компоненты сразу после нажатия на кнопку ввода в конце, но позволить пользователю выбрать последний правый компонент?Например, с помощью приведенного выше ввода я хотел бы, чтобы программа отображала что-то вроде этого:

    4 is not allowed
    1 2 3 _
    

    , чтобы пользователь мог исправить свой ввод (возможно, также изменив первые три цифры).

Извините, если этот вопрос слишком тупой!Спасибо за вашу помощь !!


РЕДАКТИРОВАТЬ: Ну, спасибо за отличные ответы, вы все были очень полезны!Жаль, что я не могу принять больше одного.

Ответы [ 5 ]

2 голосов
/ 22 января 2012

В цикле for после каждой итерации счетчик добавляется на единицу автоматически. Если вы получили неверный ввод, вы должны предотвратить увеличение счетчика. Для этого просто добавьте i--; к своему коду, когда вы вводите неверный ввод.

#include <stdio.h>

int main(void) {
    int a[6];
    printf("enter components: ");
    int i;
    for (i = 0; i < 6; i++) {
        scanf("%d", &a[i]);
        if (a[i] == 4){
           printf(" \n\n4 is not allowed, try again\n\n");
           i--;
        }
    }
    for (i = 0; i < 6; i++) {
        printf("%d ", a[i]);
    }
}
1 голос
/ 22 января 2012

Пожалуйста, смотрите ниже код:

#include <stdio.h>

int main(void) {
    int a[6];
    int i;
    bool hasError = false;
    int errorIndex = 0;
    do{
        hasError = false;
        printf("enter components: ");
        for (i = 0; i < errorIndex; i++)
            printf("%d ", a[i]);

        for (i = errorIndex; i < 6; i++) {
            scanf("%d", &a[i]);
            if (a[i] == 4 && hasError == false){
                printf(" \n\n4 is not allowed, try again\n\n");
                hasError = true;
                errorIndex = i;
            }
        }
    }while(hasError == true);
    for (i = 0; i < 6; i++) {
        printf("%d ", a[i]);
    }
}
1 голос
/ 22 января 2012

Вы можете сделать что-то вроде этого:

int i,a[6];
for (int i=0;i<6;i++) {
 scan: scanf("%d",&a[i]);
}
for (int i=0;i<6;i++) if (a[i]==4) {
 printf("4 is not allowed. re-enter the last %d numbers\n",6-i);
 goto scan;
}

обратите внимание, что в большинстве случаев лучше избегать использования goto, но в этом случае я думаю, что это естественно.

Если вы действительно хотите, вы можете напечатать первые i числа (до goto), но это сложно (и зависит от платформы), чтобы позволить пользователю изменить эти числа.

1 голос
/ 22 января 2012

Улучшение ответа Мир Милад Хоссейны (я ошибочно определил, что это бесконтрольный цикл из-под контроля ... на самом деле это именно тот бесконечный цикл, который я описал в своем комментарии) ...

Я бы написал небольшую функцию, в которой есть «белый список» (то, что вы хотите) или «черный список», то, что вам не нужно, и проверил бы каждое значение как принадлежащее или нет (в зависимости от подхода) к списку. Таким образом, вы можете хранить отдельное место, где хранятся значения, которые вы готовы принять, или значения, которые вы не принимаете, так что ваша основная функция не сильно запутывается с исключениями или включениями в «если»

поэтому ваш код будет

if(isAllowed(a[i]){
   myList[j] = a[i]; //j is your alternate counter
}
1 голос
/ 22 января 2012

Это связано с тем, что ваш терминал находится в «приготовленном» режиме. Символы даже не отправляются в программу, пока пользователь не нажмет ввод.

...