2016-01-24 38 views
2

這裏是我當前的代碼:C如何忽略用戶輸入中的空行?

int num = 0; 
char c = '#'; 

scanf("%d",&num); 
do{ 
    for (int i=0;i<num;i++){ 
     printf("%c",c); 
    } 
    printf("\n"); 
} 
while (scanf("%d", &num) == 1); 

如何我要這樣,如果用戶不輸入任何內容,該方案將不會吐出一個換行符?

任何幫助表示讚賞,謝謝!

+1

的可能的複製[獲取scanf函數退出時,它讀取一個換行符?](http://stackoverflow.com/questions/3723044/get-scanf-to-quit-when-it-reads-a-換行) –

+0

嗯,你所說的「空」,我只會調用''\ n「'的輸入並保存''」'_empty_輸入的想法。 – chux

+1

'scanf'的'%d'將忽略(跳過)前面的換行符(空格)。 – BLUEPIXY

回答

2

此代碼應爲工作,你想做什麼:

#include <stdio.h> 

int main() 
{ 
    int num = 0; 
    char c = '#'; 
    char readLine[50]; 

    while ((fgets(readLine, sizeof readLine, stdin) != NULL) && sscanf(readLine, "%d", &num) == 1) 
    { 
     for (int i=0;i<num;i++){ 
       printf("%c",c); 
     } 
     printf("\n"); 
     fflush(stdout); 
    } 
    return 0; 
} 

這段代碼的行爲如下:與fgets會讀什麼你的標準流(標準輸入)的輸入,並把它放在readLine數組。然後程序將嘗試讀取readLine變量中的數字,並將其放入具有sscanf函數的num變量中。如果讀取了一個數字,程序將執行您在問題中出現的行爲(編寫一個#字符「num」次),然後返回到循環的開頭。如果讀取了其他數字,則循環停止。

+0

您不會忽略空白行,您會停止空白行中的程序。刪除'&&(readLine [0]!='\ n')'會解決這個問題。無論如何,這是不需要的。 – chqrlie

0

一般而言,請避免scanf。在輸入流中留下未處理的垃圾非常容易。相反,閱讀整行,然後使用sscanf(或其他)來處理它。這保證你不會遇到部分讀取行,這些都很難調試。

我更喜歡getlinefgets來讀取線條。 fgets要求您猜測輸入可能會有多長時間,並且輸入可能會被截斷。 getline會分配內存來爲你讀取行,避免緩衝區溢出或截斷問題。

注意:getline is it's not a C standard function, but a POSIX one和相當近的(2008),儘管它在此之前是一個GNU擴展。一些較早的編譯器可能沒有它。

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    char c = '#'; 
    char *line = NULL; 
    size_t linelen = 0; 

    /* First read the whole line */ 
    while(getline(&line, &linelen, stdin) > 0) { 
     /* Then figure out what's in it */ 
     long num = 0; 
     if(sscanf(line, "%ld", &num) > 0) { 
      for(int i = 0; i < num; i++) { 
       printf("%c", c); 
      } 
      printf("\n"); 
     } 
    } 

    free(line); 

    return 0; 
} 

if(sscanf(line, "%ld", &num) > 0) {將忽略不圖案,的任何部分匹配,如空白行或一個完整的單詞的線路的任何線路,通過檢查多少東西相匹配。但它仍然會處理0作爲有效輸入。

$ ./test 
foo 
bar 
foo123 
12 
############ 

1 
# 
0 

2 
## 

我也感動num內循環,以保證它的重新初始化每個迭代,並把你的變量在最小範圍,以避免干擾的一般原則。我把它升級到long int更能夠處理難以預測的大數字用戶可能輸入的內容。

0

以下是我多年來使用fgets()和sscanf()函數完成輸入解析的方法。我不會寫很多C++,如果我可以將代碼保留在舊式ansi C中,那麼我就可以。 stdio.h庫中的fgets和sscanf函數是通用的,並且始終可用於任何平臺。

對於用於讀取任何內容的字符數組,我通常將LINE_SIZE設置爲256或512,即使我通常知道要讀取的行是80個字符或更少。今天任何計算機擁有超過1GB的RAM,不值得擔心分配額外的500字節。很顯然,如果你不知道該輸入線有多長,那麼你要麼必須:

猜測什麼LINE_SIZE應設置,而不用擔心它

或驗證換行符存在於線[ ]在調用fgets()之後的空字符之前。

# include <stdio.h> 

# define LINE_SIZE 256 

int main (int argc, char *argv[]) 
{ 
    FILE *fp; 
    char line[LINE_SIZE]; 
    int nn; 
    int value; 

    fp = fopen("somefile", "r"); 

    fgets(line, LINE_SIZE, fp); 

    /* 
     this way to read from standard input (i.e. the keyboard) 
     using fgets with stdin prevents compiler warning when using 
     deprecated gets function 

     fgets(line, LINE_SIZE, stdin); 
    */ 

    if (line[0] != '\n') 
    { 
     /* definitely not a blank line */ 

     nn = sscanf(line, "%d", &num); 

     if (nn == 1) 
     { 
      /* some number placed into num variable that met the 
       %d conversion for the sscanf function 
      */ 
     } 
    } 
    return 0;