2016-07-13 8 views
0

Во-первых, извините за мой плохой английский, хорошо перейдите к этому вопросу выше. Я занимался серфингом много для справки об этом вопросе на многих сайтах, но пока не нашел правильного ответа.C Программирование - Разрешить/определить/проверить «пробел (& # 32)» ввод в целое число

Я пытаюсь создать программу на языке C, которую эта программа может определить, если пользователь вводит целое число или нет, если пользователь не вводил целое число, а затем попросил попросить пользователя ввести целое число и т. Д. Все нормально, когда я использую scanf() возвращаемое значение в условном выражении, но проблема в том, что когда пользователь вводит «пробелы/пробелы/пробелы» (по коду ascii как & # 32) и нажмите «enter», моя программа останется включенной для ожидания ввода пользователем каких-либо символов или целого числа.

Мне просто жаль, что если вход «whitespace/blackspace/space», программа будет повторять запрос пользователю ввести целое число или программу просто остановить.

Вот случай код:

#include <stdio.h> 

int main() { 

    int number, isInt; 

    printf("Input a number : "); 

    do { 
     if ((isInt = scanf("%d", &number)) == 0) { 
      printf("retry : "); 
      scanf("%*s"); 
     } else if (number < 0) { 
      printf("retry : "); 
     } 
    } while (isInt == 0 || number < 0); 

    printf("%d\n", number); 

    return 0; 
} 

Я новичок в C, и любопытно об этом. Я знаю, если я использую% [^ \ n] < - код для строки scanf() и преобразовываю его в integer, программа, которую я имею в виду, будет работать правильно. Есть ли другой способ решить эту проблему, используя формат кода% d? или с помощью scanf()?

Пожалуйста, помогите мне разбить мое любопытство, Regards: D

+0

зсапЕ() не будет обрабатывать, что, как ответ на http://stackoverflow.com/questions/6582322/what-does-space-in-scanf-mean показывает. попробуйте http://stackoverflow.com/questions/3765023/how-do-i-read-white-space-using-scanf-in-c?rq=1 – Toby

+0

Прочитайте символы один за другим через 'scanf ("% c ", & character)' и преобразовать строку, считанную в integer, одним из решений. Если использование 'scanf()' не требуется, 'getchar()' должно быть лучше для этого использования. – MikeCAT

ответ

0

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

Я бы рекомендовал использовать fgets, чтобы получить строку ввода, а затем обработать с помощью sscanf. Что-то вроде этого:

#include <stdio.h> 
#include <stdlib.h> 

int main() {  
    int number=-1;  
    printf("Input a number : "); 
    do { 
     char line[80]; 
     if(!fgets(line,sizeof(line),stdin)){ 
      printf("line read error\n"); 
      exit(1); 
     } 
     if (sscanf(line,"%d", &number) !=1) { 
      printf("retry : "); 
     } else if (number < 0) { 
      printf("retry : "); 
     } 
    } while (number < 0); 
    printf("%d\n", number); 
    return 0; 
} 
+0

Вызов 'scanf ("% * s ") не является неопределенным из-за наличия символа подавления присваивания' * '; он будет читать, но не пытаться назначить следующую строку ввода. –

+0

моя ошибка ... исправление – evaitl

+0

это ответ, что я хотел, точно исправить мою проблему любопытства. Thnx bro (y)! –

0

спецификатора формата «% * s» остановится ввод символов, когда он встречает белое пространство (вкладка, пробел, символ новой строки), так что если пользователь вводит какой-либо из этих символов, они не будут потребляться ,

«% d» будет потреблять все такое ведущее белое пространство.

, когда пользователь вводит некоторые «правильный» номер, то код будет падать через к «другому» заявлению

, когда пользователь вводит некоторое значение ASCII, как «а», то «% d» закончит ввод и код перейдут в оператор 'else'. В это время переменная 'number' не будет установлена ​​ Итак, «число» будет содержать то, что каждый мусор попал в стек, где находится «числовая переменная». что «может» случиться, чтобы быть целым числом больше 0.

Значение, возвращаемое из вызова «зсапЕ()» может быть что-то другое, чем 0 или 1, как EOF

«забой» будет потребляется драйвером терминала, поэтому никогда не доходите до программы.

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

0

%s будет пропускать любые ведущие пробелы, а затем читать не-пробельные символы, пока не увидит пробелы снова. Таким образом, вызов scanf("*%s"); будет блокироваться, пока он не увидит хотя бы один символ без пробелов.

Спецификатор %[ преобразования будет не пропускать любые ведущие пробела, так что может быть приемлемая замена:

scanf("%*[^\n]"); 

Это «работает» в быстром и грязном тесте, хотя, честно говоря, лучше подход состоит в том, чтобы читать все входные данные как текст, а затем использовать strtol для преобразования текста в целевой тип. Вот рабочий пример того, что я имею в виду:

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

#define BUF_SIZE 20 

int main(void) 
{ 
    int value = -1; 
    char buf[BUF_SIZE]; 

    do 
    { 
    printf("Gimme a non-negative value: "); 
    if (fgets(buf, sizeof buf, stdin)) 
    { 
     char *newline = strchr(buf, '\n'); 
     if (!newline) 
     { 
     printf("Input too long for buffer, flushing..."); 
     while (fgets(buf, sizeof buf, stdin) && !strchr(buf, '\n')) 
      ; 
     printf("try again\n"); 
     } 
     else 
     { 
     *newline = 0; // Remove the newline character from the buffer 

     char *chk; // chk will point to the first character *not* converted 
         // by strtol. If that character is anything other 
         // than 0 or whitespace, then the input string was 
         // not a valid integer. 

     int tmp = (int) strtol(buf, &chk, 0); 
     if (*chk != 0 && !isspace(*chk)) 
     { 
      printf("%s is not a valid integer, try again\n", buf); 
     } 
     else if (tmp < 0) 
     { 
      printf("%d is negative, try again\n", tmp); 
     } 
     else 
     { 
      value = tmp; 
     } 
     } 
    } 
    else 
    { 
     printf("Input failure, bailing out completely\n"); 
     break; 
    } 
    } while (value < 0); 

    printf("value is %d\n", value); 
    return 0; 
} 

И вот пример из бега, занятий спортом каждый тестовый случай:

$ ./format2 
Gimme a non-negative value: Supercalifragilisticexpealidocious 
Input too long for buffer, flushing...try again 
Gimme a non-negative value: 123fgh 
123fgh is not a valid integer, try again 
Gimme a non-negative value: -12345 
-12345 is negative, try again 
Gimme a non-negative value: 1234 
value is 1234 

И чтобы проверить fgets неудачу, я типа Ctrl - д отправить EOF:

$ ./format2 
Gimme a non-negative value: Input failure, bailing out completely 
value is -1 
+0

cool answer too bro, thnx для помощи, собираюсь поместить это в свою библиотеку любопытства (y)! –

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

  • Нет связанных вопросов^_^