0

我希望用户输入一个 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);
}
4

6 回答 6

1

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

#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);
}
于 2013-05-31T02:24:28.980 回答
1

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

#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”)。

于 2013-05-31T02:30:52.367 回答
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不是不允许'-'
明确允许可选的前导和尾随空格。
捕获 8 位数字后的%c任何非白色字符。通过导致返回 2
扫描任何内容。%csscanf()

于 2013-05-31T05:40:58.157 回答
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;
}
于 2013-05-31T02:28:38.263 回答
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;
}

编辑:我在fgets这里使用过,atoi我认为熟悉这些功能会很好。话虽如此,这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')
    ;
于 2013-05-31T02:39:37.127 回答
-1

自从我用 C 中的格式化输入愚弄了一段时间,但尝试 scanf("%8d", &account_number);

于 2013-05-31T02:24:01.807 回答