2014-10-27 280 views
1

我這個網站,這個上看到:fscanf(fin, "%[^\n]", &p);可以用於從我的輸入文件(fin)讀成char類型指針(*p)所有字符,直到第一個輸入命中。在某些投入中,它可以正常工作,但在其他投入中則不會。什麼%[^ n]的意思是在scanf()的格式字符串

這是輸入我應該處理,我不能:

(((zahar 100 ou 3) 5 unt 100 nuca 200) 4 (lapte 200 cacao 50 zahar 100)3)20 

這是我的全部代碼:

#include <string.h> 
#include <stdio.h> 
FILE *fin, *fout; 
int main() 
{ 
    fin = fopen("reteta.in", "r"); 
    fout = fopen("reteta.out", "w"); 
    char *p; 
    p = new char[1001](); 
    fscanf(fin, "%[^\n]", &p); 
    fprintf(fout, "%s", &p); 
    return 0; 
} 
+2

匹配無限多的字符而不是'\ n',並將它們放入由coresponding參數指向的'char []'中。 (這是'char *'類型,**而不是'char **'類型。** – Deduplicator 2014-10-27 22:05:32

+2

使用Google搜索'fscanf'會將我帶到http://msdn.microsoft.com/en-us/library/kwwtf9ch.aspx三個鼠標點擊 – 2014-10-27 22:06:47

+0

請注意'new char [1001]();'不是C - 它是C++代碼 – 2014-10-27 22:18:59

回答

4

%[符號引入了一種叫做「掃描集」,這有點像正則表達式(但不如功能強大)。

在您的具體的例子就意味着格式說明指示scanf保持一致,除了一個\n(遇到不匹配的字符將終止掃描)任何掃描字符。

從C11標準:

的轉換指定包括在所述 格式字符串中的所有後續字符,直到幷包括匹配的右括號(])。支架(掃描列表)之間的 字符構成掃描集, 除非左括號後的字符是一個音調符號(^),在 這種情況下,掃描集包含不之間出現在 掃描列表所有字符旋鈕和右支架。


即使相對於一個正則表達式將其拉伸:標準簡單地說的那樣:「匹配字符的非空序列從一組預期的字符的」。因爲你想通過P,而不是「P的地址」

fscanf(fin, "%[^\n]", &p); 
        ^

&


與您的代碼,由喬納森·萊弗勒發現真正的問題是這樣的。

+0

這是它的意思,讀取從scanf到\ n字符的所有內容。通過我看到你說的是同樣的事情,或者我不明白。如果這樣做,爲什麼它不適用於該輸入? – 2014-10-27 22:15:07

+0

@MihneaGafton你沒有解釋它不工作的方式。究竟發生了什麼以及它與您的期望有什麼偏差? – cnicutar 2014-10-27 22:19:19

+0

對不起,沒有正確解釋,當我嘗試編譯該代碼與該輸入時,它給了我在控制檯上的無限循環像錯誤。 – 2014-10-27 22:21:42

2

% introduces a format-specifier[意味着它是一個掃描設置,並在掃描組第一位置打開它,^從「匹配所有的」逆轉爲「匹配所有」,\n是換行字符,]關閉掃描設置。

因此,這意味着:無限地匹配很多不是\n的字符,並將它們放入參數指向的char[]

該論點因此必須具有類型char*
&p恰恰是一個地址 - 太多,並且它指向的緩衝區(new char[1001])是無限的數量級太小。

限制匹配的長度(在掃描集和%之間放置1000)。
或者,更好的是,使用fgets


其他景點:

  1. 你的緩衝區應該棧上分配的,因爲它是足夠小:

    char buf[1001]; 
    
  2. 或者,至少使用智能指針,所以你別忘了delete []它:

    std::unique_ptr<char> p = new char[1001]; 
    
  3. 爲什麼你重新初始化它?這是多餘的。使用new char[1001]而不是new char[1001]()
  4. 不要忘記檢查fscanf的返回值,它應該是成功分配的數量。
  5. C++(和C99)在main的末尾有一個隱含的return 0;
  6. 你真的應該關閉你打開的所有文件(fopen - >fclose)。
+0

「限制匹配的長度(在掃描集和%之間放置1000)」。這意味着像'fscanf(fin,「%1000 [^ \ n]」,&p);''寫入,我試過了,它顯示出一個類似於第一種情況的控制檯錯誤的無限循環。 – 2014-10-27 22:23:56

+0

@jonathan:我不認爲「無限」是一個錯字,儘管「無限期」更準確,但並不強調無限的本質。 – 2014-10-27 22:30:02

+1

@MihneaGafton:??無論如何,你是否閱讀過有關額外'''有bug的部分? – Deduplicator 2014-10-27 22:30:03

相關問題