2015-03-23 7 views
2

Эта программа выполняет следующие действия:STRCMP - цикл, пока не вход

  1. сканирует строку текста ввода полукокса [15];
  2. Сравнивает его с char password [] = "1sure";
  3. Петли, если строки не совпадают.
  4. Завершается, если строки совпадают.

Программа пеет, пока строки не совпадают. Тем не менее, я также хочу, чтобы программа зациклилась, если ничего не введено, и пользователь просто нажимает enter. Я попытался использовать функцию isgraph, но это приводит к сбою программы. Я прокомментировал этот раздел в коде. Может ли кто-нибудь предложить, как заставить программу зацикливаться, если нет ввода?

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char password[] = "1sure"; 
    char input[15]; 

    do 
    { 
     printf("Password: "); 
     scanf("%s", input); 

     if(strcmp(password,input)==0) 
     { 
      printf("Password accepted."); 
      putchar('\n'); 
      return(0); 
     } 
     /*else if(isgraph(input)==0) 
     { 
      printf("No input detected."); //Program crashes with this segment. 
      continue; 
     }*/ 
     else 
     { 
      printf("\nInvalid password.\n"); 
      continue; 
     } 
    } 
    while(1); 
} 
+1

Используйте [ 'fgets()'] (http://en.cppreference.com/w/c/io/fgets) вместо 'scanf' и отбросить новую строку. – WhozCraig

+2

Вызов 'scanf',' scanf ("% s", input); 'не будет завершен до тех пор, пока пользователь не войдет в небелый пробел. Просто нажатие Enter не приведет к тому, что ничего не будет прочитано «input» - программа будет просто ждать. –

+0

Проще включить в выходное сообщение новую строку, когда пароль принят, чем использовать 'printf()' plus 'putchar()'. Не забывайте, что стандартная ошибка предназначена для сообщения сообщений об ошибках. –

ответ

3

Программа может выглядеть следующим образом

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 

int main(void) 
{ 
    char password[] = "1sure"; 
    char input[15]; 

    do 
    { 
     printf("\nPassword: "); 

     if (fgets(input, sizeof(input), stdin) == NULL) 
     { 
      printf("An error occured or input was interrupted\n"); 
      return 0; 
     } 

     size_t n = strlen(input); 

     while (n && isspace(input[n-1])) input[--n] = '\0'; 

     if (input[0] == '\0') 
     { 
      printf("No input detected.\n"); 
      continue; 
     } 
     else if(strcmp(password, input) == 0) 
     { 
      printf("Password accepted.\n"); 
      return(0); 
     } 
     else 
     { 
      printf("\nInvalid password.\n"); 
      continue; 
     } 
    } while(1); 
} 
0

Проверьте возвращаемое значение зсапЕ (он должен вернуть 1), чтобы продолжить остальную часть кода

printf("Password: "); 
char line[15]; 
if(fgets(line,15,stdin)!=NULL) { 
    if(scanf("%s", input)==1) { 
     if(strcmp(password,input)==0) { 
    ... 
    } 
} 
+0

Просто проверка возвращаемого значения 'scanf ("% s ", input)' не является полным исправлением по всем перечисленным выше причинам (ведущие символы новой строки, неопределенное поведение ...) – chqrlie

+0

@chqrlie спасибо за отзыв, я поправлю ответ – dvhh

0

Просто проверить возвращаемое значение scanf.

if (scanf("%s",input) != 1) 
     continue; 
... 
... 

Или иначе вы можете это сделать.

while(scanf("%s",input) != 1)// It will continue the loop until the correct input come. 
     continue; 
+3

Это не сработает неугодно. 'Scanf ("% s ")' может работать только при возникновении EOF. '% s' потребляет ведущие пробелы, включая символы новой строки. –

+0

'scanf ("% s ", input)' может вызвать переполнение буфера. Тщательно обработанный ввод может привести к недопустимому паролю (среди других неопределенных действий) – chqrlie

2

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

Вместо этого вы можете прочитать строку с fgets. Обратите внимание, что я добавил проверки ошибок:

if (! fgets(input, sizeof input, stdin)) 
    break; 

К сожалению fgets имеет странность в том, что она ставит символ новой строки в буфер, так что вы должны удалить это; один из способов сделать это:

char *newline = strchr(input, '\n'); 
if (newline) 
    *newline = '\0'; 

Затем вы можете перейти к strcmp и остальные части цикла.


Другие примечания: Если вы не получили ошибок компилятора для isgraph(input), то вам необходимо выяснить, как ссылаться на ваш компилятор правильно. Этот код является незаконным, и если ошибки не отображаются, вы можете пропустить другую полезную информацию, которую компилятор мог бы вам рассказать.

Кроме того, нет else после return. Оператор return не может потерпеть неудачу. A continue, поскольку последняя строка цикла аналогично избыточна.

+1

'if (input [strlen (input) - 1] == '\ n')' может вызывать UB. Рекомендовать http://stackoverflow.com/a/28462221/2410359 или застраховать '* input! = 0'. – chux

+0

@chux Я не вижу, как это может вызвать UB; 'fgets' не может возвращать ненулевое значение, а также выводить что угодно, кроме непустой строки с нулевым завершением. (Ну, я думаю, это могло бы быть, если размер буфера был 1) –

+0

'fgets()' читает _line_ ('char' до и включая' '\ n''), а не _string_ (' char' вплоть до и включая ' '\ 0''). Ввод может содержать встроенный '' \ 0'', такой как «\ 0abc \ n». 'fgets()' в этом случае заполняет 'input' с помощью« \ 0abc \ n \ 0 ». Затем 'input [strlen (input) - 1] = '\ 0';' устанавливает значение перед массивом 'input'. – chux

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