将用户输入限制为8位数

我希望用户输入一个8位数的帐号。 我有的代码似乎适用于所有内容,除非你有多个字母,即:’bbb’作为输入。 如果发生这种情况,它会运行while循环3次,显示printf,但不要求另一个输入。

关于如何解决这个问题的任何意见,或者更好的方法都是受欢迎的!

现在,我正在使用:

#include  int main() { int return_val = 0; int account_number = 0; int within_range = 0; printf("Please enter your 8 digit account number:\n"); return_val = scanf("%d", &account_number); getchar(); getchar(); if((account_number > 9999999) && (account_number  9999999) && (account_number < 99999999)) { within_range = 1; } } printf("Account #: %d", account_number); } 

如果你将输入读作一串字符(使用fgets )并使用sscanf从那里解析它会有帮助吗? 你不必担心额外的getchar

 #include  int get_acct_num() { char line[80]; int acct_num; int return_val = 0; printf("Please enter your 8 digit account number:\n"); fgets ( line, sizeof ( line ), stdin ); return_val = sscanf(line, "%d", &acct_num); if ( return_val != 1 ) return ( 0 ); if ( ( acct_num < 10000000 ) || ( acct_num > 99999999 ) ) return ( 0 ); return ( acct_num ); } int main() { int account_number = 0; while ( ! ( account_number = get_acct_num() ) ) printf("Invalid account number. Account number must be 8 digits.\n"); printf("Account #: %d", account_number); } 
 #include  #include  #include  #include  int main() { int account_number = 0; int inval = 0; char acc_buf[256]; printf("Please enter your 8 digit account number:\n"); scanf("%s", acc_buf); if (strlen(acc_buf) == 8) { for (int i = 0; i < 8; i++) if (!isdigit(acc_buf[i])) { inval++; break; } } else inval++; if (!inval) { account_number = atoi(acc_buf); printf("Account #: %d\n", account_number); } return 0; } 

在这种情况下,最好解析一个字符串

 #include  ... char input[200]; scanf("%s", input); int len = strlen(input); int dig = 0; if (len == 8) { for ( ; dig 

代码确保我们有8位数字,输入中没有其他内容(打印“OK”)。

我可以建议稍微改写一下吗?

 #include  #include  /* this is for strlen */ #include  /* this is for atoi */ int main() { char input [55]; /* this is to store the user input */ int account_number = 0; printf("Please enter your 8 digit account number:\n"); while (fgets(input, 55, stdin)[0] == '\n') ; /* this is a safer way to get input, loop until there is input, ignore new lines */ account_number = atoi(input); /* convert to an int */ if (account_number < 10000000 || account_number > 99999999) return -1; /* quit if invalid input */ printf("Account #: %d\n", account_number); return 0; } 

编辑:我在这里使用fgetsatoi因为我认为熟悉这些function会很好。 说过atoi不一定是转换为数字的最佳方式。 Strtol更可靠,但使用起来有点复杂。

这是在这种情况下使用strtol一种方法:

  char* temp = 0; account_number = strtol(input, &temp, 10); /* convert to an int */ 

更多关于在这里将字符串转换为数字的主题。

EDIT-2:考虑到chux的注释,循环也可以像这样构造:

 char* out; do { out = fgets(input, 55, stdin); } while (out == NULL || out[0] == '\n') ; 

我真的不喜欢使用scanf() ,更喜欢fgets() ,然后是sscanf()
详情如下。
2个关键线:

 if (fgets(buf, sizeof(buf), stdin) == NULL) ... while (1 != sscanf(buf, " %8lu %c", &AccontNummner, &ch)); 

 #include  #include  // Get 8 digit account number. Returns -1 on I/O error or EOF // Parsing error just tries again. long Get8DigitAccountNumber(void) { const char *prompt = "Enter 8 digit account number: "; unsigned long AccontNummner; char ch; // Extra text char buf[1024]; do { // or while (1) ch = '\0'; printf(prompt); fflush(stdout); // Appears to be needed on some systems. prompt = "Error, try again: "; // Used on re-try if (fgets(buf, sizeof(buf), stdin) == NULL) { return -1; // handle I/O error } // If not _exactly_ one 1-8 digit field parsed, then try again. // Leading and trailing whitespaces are OK } while (1 != sscanf(buf, " %8lu %c", &AccontNummner, &ch)); return (long) AccontNummner; } int main() { long AccontNummner; while ((AccontNummner = Get8DigitAccountNumber()) >= 0) { printf("# %lu\n", AccontNummner); } return 0; } 

如果你想准确读取8位数……

  int n1 = 0; int n2 = 0; } while ((1 != sscanf(buf, " %n%8lu%n %c", &n1, &AccontNummner, &n2, &ch) || ((n2 - n1) != 8)); 

可接受的格式:[可选空格] [1-8位] [可选空白] [仅此而已]
sscanf()格式: " %8lu %c"
使用%u代替%d不允许使用'-'
明确允许可选的前导和尾随空格。
%c在8位数字后捕获任何非白色字符。
通过%c扫描任何内容会导致sscanf()返回2。

已经有一段时间了,因为我在C中使用格式化输入,但尝试scanf(“%8d”,&account_number);