Я хотел бы знать, как лучше всего выйти из цикла do-while, не используя EOF или другой номер.
Есть ли способ ввести символ, чтобы пользователь мог выйти из цикла?
Я пытался написать printf("Enter a number ('x' to exit):, но это не работает.
Вы знаете другой метод?
Я не могу использовать EOF, потому что иначе программа не будет считать -1 как число, а число -1 будет использоваться исключительно для выхода из цикла.

#include <stdio.h>

int even(int number);

int main(){
    int n;
    do{
        printf("Enter an integer (x to terminate): ");
        scanf("%d", &n);
        if(n=='x'){
            break;
        }
        printf("%d\n", even(n));
    }while(n!='x');
    return 0;
}

int even(int number){
    if(number%2==0){
        return 1;
    }else{
        return 0;
    }
}
c
0
user10251618 20 Авг 2018 в 22:30

3 ответа

Лучший ответ

Сохранить возвращаемое значение из scanf(), как в

 int scanreturn=0;
 /* ... */
 scanreturn= scanf("%d", &n);

Затем используйте это как условие для do-while

}while (scanreturn == 1);

Это работает, потому что scanf() возвращает количество успешно отсканированных полей ввода.
Это будет 1, если одно целое число было успешно отсканировано.
Когда вводится «x» или что-либо, не похожее на целое число, цикл заканчивается.

Сравните https://en.cppreference.com/w/c/io/fscanf

Возвращаемое значение:
Количество успешно полученных аргументов (может быть ноль в случае сбоя сопоставления до первого получения аргумент) или EOF, если сбой ввода произошел до Первый полученный аргумент был назначен.

Или цитата из стандарта C 7.21.6.4, например, http://port70.net/~nsz/c/c11/ n1570.html # 7.21.6.4

... функция scanf возвращает количество назначенных элементов ввода, которое может быть меньше предусмотренного или даже равно нулю в случае неудачного раннего сопоставления.

2
Yunnosch 20 Авг 2018 в 20:01
int n, val=1;

do{
    printf("Enter an integer (x to terminate): ");
    val=scanf("%d", &n);
    printf("%d\n", even(n));
}while(val!=0);

Scanf () возвращает количество успешно прочитанных элементов.

Ты тоже можешь это сделать:

int n;
char c[25];

do{
    printf("Enter an integer (x to terminate): ");
    scanf("%24s", c);
    printf("%d\n", even(atoi(c)));
}while(c[0]!='x');
0
Fábio Morais 20 Авг 2018 в 20:07

У вас есть несколько способов пойти с этим.

scanf возвращает количество успешных преобразований и назначений. Если вы ожидаете ввод одного десятичного целого числа и первое, что вы видите, это 'x', то у вас ошибка соответствия , и scanf вернет 0. Итак, вы может сделать что-то вроде

printf( "Gimme a number: " );
if ( scanf( "%d", &n ) == 1 )
{
  // do something with n
}
else
{
  if ( !feof( stdin ) )
  {
    // user entered something that isn't a decimal digit
  }
  else
  {
    // EOF signaled on input stream (ctrl-D, ctrl-Z, EOF from redirected file, etc.).
  }
}

Проблема состоит в том, что это оставляет бесподобный ввод в потоке, чтобы запутать следующее чтение. Лучшее решение IMO - это то, что читает все как текст, а затем использует strtol для преобразования текста в целое число.

#include <stdlib.h> // for strtol
#include <ctype.h>  // for isspace

#define MAX_INPUT_LENTH 13 // enough for 10 decimal digits plus sign plus newline plus string terminator

char input[MAX_INPUT_LENGTH+1];

printf( "Gimme a number: " );
if ( fgets( input, sizeof input, stdin ) )
{
  char *chk; // will point to first character in input that *isn't* a
             // decimal digit
  int tmp = strtod( input, &chk, 10 );
  if ( !isspace( *chk ) && *chk != 0 )
  {
    // input is not a valid decimal integer
  }
  else
  {
    n = tmp; // don't assign n until you know you have valid input
  }
}
else
{
  if ( feof( stdin ) )
  {
    // end-of-file signaled on input stream
  }
  else
  {
    // error during input
  }
}

Ни одно из этих решений не находится в цикле, но вы должны быть в состоянии выяснить, как интегрировать их в циклическую структуру.

0
John Bode 20 Авг 2018 в 20:01
51937358