2013-05-27 31 views
0

請看看這個代碼片段:分配抑制標誌的fscanf

char line[80]; 
if(fscanf(stdin, "%*[\t\v\f ]%79[^\n]", line) != EOF) 
     printf("%s\n", line); 

輸出:

$ gcc line.c -o line 
$ ./line 
One space at the beginning. 
One space at the beginning. 
$ ./line 
No space at the beginning. 

$ 

現在在No space at the beginning情況下,爲什麼不打印整個字符串,因爲它是什麼?如果在該行的開頭沒有空格,製表符或分頁符

$ gcc --version 
gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 

回答

0

scanf將在第一場比賽%*[\t\v\f ]失敗。一旦失敗,它將不會嘗試匹配模式的其餘部分。

此外,您不需要手動匹配這些字符,格式字符串中的一個空格將擴展爲輸入字符串中任意數量的空格。請參閱isspace的文檔以檢查哪些字符被視爲空白。

+0

對不起,無意中編輯了你的答案,而不是我自己的答案。 – hmjd

+0

@hmjd我認爲是這樣:) – zakinster

2

由於沒有匹配"%*[\t\v\f ]"而失敗,因此未處理後續格式說明符%79[^\n],並且未分配line。要跳過前面的空格用一個空格代替掃描集:

if(fscanf(stdin, " %79[^\n]", line) == 1) 
    printf("%s\n", line); 
+0

'fscanf'在'開始時一個空格'的情況下失敗,儘管不是在第一個字符。並且不能在這裏使用空格,因爲它會消耗位於每行末尾的'\ n'字符,如果有空行,這會產生問題。即僅包含「\ n」的行。 – rootkea

+0

@rootkea,我不確定你是什麼意思_不是在第一個字符_? – hmjd

+0

對不起,我的意思是'[\ t \ v \ f]'在'開始時有一個空格'的情況下失敗,儘管不是在第一個字符。 – rootkea

0

好像找不到場以及由@hmjd解釋掃描退出你有麻煩。

注意:使用fgets()是一個更好的辦法,但OP風格堅持:

// consume select leading whitespaces, if any, but not \n 
fscanf(stdin, "%*[\t\v\f ]"); 

// Scan non-eol chars 
char line[80]; 
if (fscanf(stdin, "%79[^\n]", line) == 1) { 
    printf("%s\n", line); 
} 

// scan a single EOL 
char eol[2]; 
if (fscanf(stdin, "%1[\n]", eol) == 1) { 
    ; // EOL found 
} 

分離至3個fscanf()電話,每種格式,依次嘗試,即使較早的一個失敗。