2014-06-08 75 views
0

我想讀取結構中的兩個變量,但我面臨使用scanf的一些問題。下面是代碼:問題與scanf和結構

typedef struct { 
    int pc; 
    char* label; 
} sb; 

...這裏是結構的實例:

sb input; 
fscanf (in, "%s%d", input.label, &(input.pc)); 
printf ("%s %d\n", input.label, input.pc); 

我期待爲輸出「C-字符串」和一個整數,但由於某種原因,給了我:(空)和-971303966。

回答

4

主要問題是您沒有真正在標籤結構中分配任何存儲空間。一個解決方案是申報更改爲:

typedef struct { 
    int pc; 
    char label[80]; 
} sb; 

但請注意,代碼現在是危險的,因爲它讀入緩衝區不向讀任何限制,因此它可以溢出緩衝區。

+1

「用%s將整行的scanf」 並非如此。 ''%s「'會導致'fscanf()'在非空白區域進行掃描,至少不包括該行的'\ n''。 – chux

+0

謝謝 - 忘記了%s的語義 - 現在我記得我爲什麼不使用它。更新。 – DrC

1

結構中的「標籤」只是一個指針,什麼都不能容納一個字符串。你必須要麼分配一些內存爲它

Input.label = (char*)malloc(122); 

或更改結構來

typedef struct { int pc; char label[122]; } sb; 

要當心左右的內存你分配的字符串的數量。最好使用fscanf_s,這樣你可以聲明最大讀取長度。

+0

好的,那是有效的。但是如果我把這兩個變量放在結構之外,代碼就可以工作。 http://pastebin.com/d8q0bvAE – Guilherme

+1

你真是幸運 - 它也可能已經崩潰。它將取決於未初始化的變量標籤包含的值。 – DrC

+0

這個問題被標記爲[c],而不是[C++],所以你需要使用'malloc'而不是'new'。 – jwodder

0

fscanf(in, "%s%d", input.label, &(input.pc))導致未定義的行爲(UB),因爲沒有與input.label關聯的存儲器,其中fscanf()嘗試保存。

1)避免使用fscanf()。推薦fgets()/sscanf()
2)檢查類似函數的任何scanf()的返回值。
3)分配空間label

void Read_sb(sb *data) { 
    sb->pc = 0; 
    sb->label = NULL; 

    char buf[100]; 
    if (fgets(buf, sizeof buf, stdin) == NULL) Handle_IOErrroOrEOF(); 

    char s[sizeof buf]; 
    if (sscanf(buf, "%s%d", s, &sb->pc) != 2) Handle_FormatError(); 
    sb->label = strdup(s); 
}