2013-05-31 79 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.