将用户输入限制为8位数

时间:2013-05-31 02:20:04

标签: c validation int

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

欢迎任何有关如何解决此问题的建议,或更好的方法!

现在,我正在使用:

#include <stdio.h>

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 < 99999999))
{
    within_range = 1;
}

while ((return_val != 1) || (within_range != 1))  
{
    printf("Invalid account number. Account number must be 8 digits.\n");
    printf("Please enter your 8 digit account number: \n");
    //scanf("%d", &clear);
    return_val = scanf("%d", &account_number);
    getchar();
    getchar();

    if((account_number > 9999999) && (account_number < 99999999))
    {
        within_range = 1;
    }
}

printf("Account #: %d", account_number);
}

6 个答案:

答案 0 :(得分:1)

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

#include <stdio.h>

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);
}

答案 1 :(得分:0)

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
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;
}

答案 2 :(得分:0)

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

#include <ctype.h>
...

char input[200];

scanf("%s", input);

int len = strlen(input);
int dig = 0;

if (len == 8) {
  for ( ; dig<len ; dig++) if ( ! isdigit(input[dig])) break;
}

if (dig == 8) printf("OK\n");
else printf("Not ok\n");

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

答案 3 :(得分:0)

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

#include <stdio.h>
#include <string.h> /* this is for strlen */
#include <stdlib.h> /* 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因为我认为熟悉这些功能会很好。说atoi不一定是转换为数字的最佳方式。 Strtol更可靠,但使用起来有点复杂。

这是在此上下文中使用strtol的一种方法:

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

有关将字符串转换为数字here的主题的更多信息。

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

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

答案 4 :(得分:0)

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

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

解决方案

#include <stdio.h>
#include <stdlib.h>
// 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.

答案 5 :(得分:-1)

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