2017-08-29 31 views
1

我想輸入一個字符並獲取相應的ASCII整數作爲輸出。我使用getchar()獲取輸入,並在while中創建一個無限循環,輸入'q'時循環會中斷。我的代碼是 -在C中的無限循環內使用getchar()

#include <stdio.h> 

int main() { 
    int c; 

    printf("Enter a character(press q to exit):\n"); 

    while(1) { 
     c = getchar(); 
     printf("%d\n",c); 

     if(c == 'q') 
      break; 
    } 

    printf("End of the program"); 
    return 0; 
} 

當輸入q,退出程序時,程序運行正常。但是如果我輸入任何其他字符,數值最後會加上10。例如,如果我輸入i,則輸出爲

Enter a character(press q to exit): 
i 
105 
10 
I 
73 
10 

任何字符都會在結尾添加10。我究竟做錯了什麼?

+4

10是'\ n'(換行符)的ASCII代碼。 –

+1

[如何避免用任何getchar() ](https://stackoverflow.com/questions/1798511/h ow-to-avoid-press-enter-with-any-getchar) – MCG

+0

我不認爲這是一個騙局,@MCG。它處理如何立即獲取角色(原始模式,基本上)。這更多地問'10'是從哪裏來的。 – paxdiablo

回答

2

10是由於您在每行末尾按ENTER而被放置在緩衝區中的ASCII換行符。

如果要忽略這些字符,只是不作用於他們:

#include <stdio.h> 
int main (void) { 
    int c; 
    printf ("Enter a series of characters (q will exit): "); 
    for (;;) { 
     c = getchar(); 
     if ((c == 'q') || (c == EOF)) // stop if EOF or 'q'. 
      break; 
     if (c != '\n')    // only print non-newlines. 
      printf ("%d\n", c); 
    } 
    printf ("End of the program"); 
    return 0; 
} 

請注意,我也檢查在循環文件的末尾,否則返回值將導致相當惱人的無限循環。

1

你可以改變行

printf("%d\n",c); 

if (c != '\n') printf("%d\n",c); 

至於其他指出的那樣,您使用的打印換行符。使用上面的'if',確保只打印不是換行符的字符。

2

當您使用getchar()時,您作爲C程序員的主要工作是爲帳戶輸入緩衝區中的所有字符。當你進入a並按返回getchar();讀取'a',但留下由輸入緩衝區stdin返回產生的'\n'。在下一次循環中,代碼似乎會繞過任何提示而無需等待輸入 - 爲什麼?,因爲getchar()已經有一個字符正在等待閱讀--。

所以這些面向字符的輸入任何問題的任何,你必須把你的會計師帽子上,佔留在stdin每個字符。有幾種方法可以做到這一點。 Paxdiablo展示了一個非常好的方法。另一種類似的方法是利用幫助函數讀取並丟棄保留在stdin中的所有字符。例如,如果您打算輸入'a',但是Cat在鍵盤上輸入緩衝區"asdfdeeees",在讀取'a'後,下列字符仍然爲"sdfdeeees\n"。你需要一個簡單的方法來丟棄所有剩下的字符。

下通過不斷讀書,直到'\n'EOF遇到提供了一個名爲empty_stdin做到這一點簡單的輔助功能(它可以返回的最後一個字符(或EOF),以允許用戶檢查手動取消輸入與一個按Ctrl + d Linux或Ctrl + Z鍵上windoze。

#include <stdio.h> 

/* helper function - empty all chars that remain in stdin */ 
int empty_stdin() 
{ 
    int c = getchar();    /* get 1st char remaining in stdin */ 

    while (c != '\n' && c != EOF) /* while not '\n' or EOF, get next */ 
     c = getchar(); 

    return c; 
} 

int main (void) { 

    while (1) {  /* infinite loop for input */ 
     int c; 

     printf ("Enter a character (press q to exit): "); 
     c = getchar();     /* read character */ 

     if (c == '\n')     /* is it a newline? */ 
      continue;     /* if so, continue */ 
     if (c == EOF) { /* end-of-file, from ctrl+d, or ctrl+z (windoze) */ 
      putchar ('\n');    /* tidy up with \n */ 
      break;      /* bail    */ 
     } 
     if (c == 'q')     /* did user quit? */ 
      break;      /* bail    */ 

     printf ("'%c' is integer: %d\n", c, c); 

     if (empty_stdin() == EOF) { 
      putchar ('\n');    /* tidy up with \n */ 
      break; 
     } 
    } 

    return 0; 
} 

實施例使用/輸出

下面是一個會話的輸出,其中單字符,多字,(和任何字符,只是返回壓,以及每個這些可能出現的情況是沒有問題的處理:

$ ./bin/getchar_min 
Enter a character (press q to exit): A 
'A' is integer: 65 
Enter a character (press q to exit): BC and other stuff 
'B' is integer: 66 
Enter a character (press q to exit): 
Enter a character (press q to exit): Z 
'Z' is integer: 90 
Enter a character (press q to exit): a 
'a' is integer: 97 
Enter a character (press q to exit): z 
'z' is integer: 122 
Enter a character (press q to exit): Q 
'Q' is integer: 81 
Enter a character (press q to exit): q 

看看看所有的答案,並把你的會計師的帽子。看看每個方法是否成功,在再次提示輸入更多輸入之前考慮緩衝區中的所有字符。同樣重要的是檢查EOF,這是用戶必須通知信號取消輸入而不使用'q'或產生SIGINT中斷信號的唯一方式。 在Linux上按Ctrl + C。如果您有任何其他問題,請告訴我。


編輯

注:我添加了一個「整潔了\n」捕每個EOF提供在執行結束時適當換行後(所以你的下一個終端提示符後不啓動從你的程序輸入的最後一個提示 - 通過終端的1/2方式:)

+0

非常感謝你解釋它非常好! – Rain013