2013-05-31 80 views
0

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

任何关于如何解决这个问题的建议,或者更好的方法,都是值得的!

现在,我使用的是:

#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); 
} 
+2

你或许应该读它作为一个字符串,然后验证其长度和数字内容,那么最终转换为整数。 – jarmod

回答

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

这已经有一段时间,因为我用C与格式化输入上当,但尝试的scanf( “%8D”,& ACCOUNT_NUMBER);

+1

这不起作用。它根据需要查找最多8位数字输入但不是8位数字。 – unxnut

+0

我没有看到它需要在哪里有一个8位掩码,只有8位数字输入。在这里推测,但这看起来像一个家庭作业,所以我认为使用是一个错误(尽管这是一个很好的方法)。但是,您可以添加前导零来获取printf语句的格式说明符中的8位帐号。 –

+1

我相信这是一项家庭作业,但他做了一个诚实的努力,并被卡住了。我相信这是一个8位掩码,因为他已经构建了他的原始代码,检查8位数字输入。 – unxnut

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; 
} 
+0

这将工作,但需要。我很确定“%8d”只会使用。 –

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

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 */ 

更多关于字符串转换为数字here的主题。

EDIT 2: 考虑到chux的评论,环可以构造这样太:

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

在极少数情况下,EOF(通过重定向输入)或I/O错误会导致'fgets()'返回NULL。在这些特殊情况下,'fgets(input,55,stdin)[0]'可能会崩溃。 – chux

+0

注意到,谢谢,我更新了我的帖子,提出了一种简单的方法来处理NULL。 – Nobilis

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.