2015-09-26 5 views
0

Я новичок в программировании на C, и я хочу, чтобы все мои элементы массива были целыми, кроме первого элемента.Бесконечный цикл при вводе недопустимого ввода

Я написал следующий код, но цикл никогда не останавливается после ввода неправильного ввода.

bool validate_int(char input[]){ 
    fgets(input,10, stdin); 
    for(int i = 1; i < strlen(input); ++i) { 
     if(!isdigit(input[i])){ 
      i = 1; 
      fgets(input,10, stdin); 
     } 
     else{ 
     } 
    } 
    return true; 
} 
+3

Вы никогда не должны игнорировать возвращаемое значение операции ввода. Ваш подход нарушен без ремонта. –

+0

@KerrekSB Uh ... Только если требуется проверка ошибок. Я слышал, что люди говорят это много, но серьезно, это, вероятно, крошечная игрушечная программа для обучения строковым операциям, а не для изучения ошибок ввода-вывода. – immibis

+0

Я просто хочу проверить элементы массива, которые начинаются с индекса no 1, является целым, а не другим типом. –

ответ

2

У вашего кода есть некоторые проблемы. Вот лучший способ сделать это (непроверенные):

bool validate_int(char input[]) /* Bad function name; See @Filipe's comment */ 
{ 
    for(;;) /* Infinite loop */ 
    { 
     if(fgets(input, 10, stdin) == NULL) /* If fgets failed */ 
     { 
      puts("fgets failed"); 
      return false; 
     } 

     int i, len = strlen(input); 

     if(len > 0 && input[len - 1] == '\n') /* If there is a newline character at the end of input */ 
      input[--len] = '\0'; /* Replace the '\n' with '\0' and decrement len */ 

     if(!isalpha(input[0])) /* If the first character of input is not an alphabet */ 
      continue; /* Loop again */ 

     if(len == 1) /* There is no number */ 
      continue; 

     for(i = 1; i < len; ++i) 
     { 
      if(!isdigit(input[i])) /* If not a digit */ 
       continue; /* Loop again */ 
     } 

     break; /* Get out of the loop */ 
    } 

    return true; 
} 

Более лучше всего было бы отделить ввод и проверку в двух отдельных функций (непроверенные):

bool getInput(char input[]) 
{ 
    if(fgets(input, 10, stdin) == NULL) /* If fgets failed */ 
    { 
     puts("fgets failed"); 
     return false; 
    } 

    int len = strlen(input); 

    if(len > 0 && input[len - 1] == '\n') /* If there is a newline character at the end of input */ 
     input[--len] = '\0'; /* Replace the '\n' with '\0' and decrement len */ 

    return true; 
} 

bool validate(char input[]) 
{ 
    if(!isalpha(input[0])) /* If the first character of input is not an alphabet */ 
     return false; 

    int i, len = strlen(input); 

    if(len == 1) /* There is no number after the character */ 
     return false; 

    for(i = 1; i < len; ++i) 
    { 
     if(!isdigit(input[i])) /* If not a digit */ 
      return false; 
    } 

    return true; 
} 

и в вызывающей функции (опять же, непроверенные),

char input[10]; 
if(getInput(input)) 
{ 
    if(validate(input)) 
    { 
     puts("Input is in correct format"); 
    } 
    else 
    { 
     puts("Input is in wrong format"); 
    } 
} 
else 
{ 
    puts("Failed to get input"); 
} 
+0

Я думаю, что вы называете 'strlen' слишком много раз. Я думаю, что 'len' должен быть рассчитан (' int len ​​= strlen (input); ') сразу после вызова' fgets' и проверки его возвращаемого значения. iThe 'len' следует использовать для проверки новой строки и должен быть отрегулирован (уменьшен), если новая строка будет удалена. – MikeCAT

+0

Спасибо. Ред. Надеюсь, он выглядит хорошо. –

+0

Не следует ли показать OP хороший способ сделать это? Отделив вход от проверки? – Cubia

1

попробовать этот

bool validate_int(char input[]){ 
    bool valid; 

    do{ 
     valid = false; 
     fgets(input,10, stdin); 
     for(int i = 1; input[i] && input[i] != '\n'; ++i) { 
      if(!isdigit(input[i])){ 
       valid = false; 
       break; 
      } else { 
       valid = true; 
      } 
     } 
    }while(!valid); 
    return true; 
} 
+0

@thanks много парней. –

2

Вот еще один подход, который я бы, который должен уборщик IMO:

Это ваша функция проверки:

bool customValidation(char *string) 
{ 
    int len = strlen(string); 
    if (!isalpha(string[0]) || (len > 1 && !isdigit(string[1]))) 
     return false; 

    for (int i = 1; i < len && string[i] != '\n'; ++i) 
     if (!isdigit(string[i])) 
      return false; 

    return true; 
} 

Это, как вы бы использовать:

char input[10]; 
do 
{ 
    fgets(input, 10, stdin); 
} while (!customValidation(input)); 

Очевидно, что вы должны переименовать customValidation() в нечто более значимое.

+0

@CoolGuy Прошло некоторое время с тех пор, как я использовал fgets(), я старался добавить дополнительный символ для размещения «\ 0». Ред. – Cubia

+0

Я думаю, что ваш код не работает должным образом, когда вход имеет одну цифру, например: 'A \ n' –

+0

@CoolGuy Добавлена ​​проверка, чтобы, если в первой позиции нет цифры, она не удастся. – Cubia

-1

Проверьте это:

int a_Length = 10; 
char input[a_Length]; 
fgets(input,a_Length, stdin); 
for(int i = 1; i < strlen(input); ++i) { 
    if(!isdigit(input[i])&& input[i]!='\n'){ 
     i = 0; 
     printf("Again try: "); 
     if (input[a_Length - 1 ]!='\n') 
      getchar(); 
     fgets(input,10, stdin); 
    } 
} 
+0

1) Вопрос о C, а не C++ 2) 'fgets' не оставляет символ новой строки в стандартном потоке ввода. Он потребляет его и сохраняет его в 'input' (при условии, что в' input' есть пробел). –

+0

Можете ли вы запустить 'fgets (input, 10, stdin), char c = getchar();'? объясните, почему char c = '\ n' получает ?? @ CoolGuy –

+0

Что такое ввод? Это 9 символов, за исключением '\ n'? –

Смежные вопросы