2014-12-23 48 views
1

我成功地打開了一個包含初始鍵值對的文件。代碼如下所示:fscanf讀訪問段錯

char key_tmp[30]; 
int value_tmp, status_index; 

FILE *ZMU_Init_fd = NULL; 
ZMU_Init_fd = fopen("zmu/zmu.cfg", "r"); 

if(ZMU_Init_fd == NULL) 
{ 
    printf("Could not open file"); 
    strerror(errno); 
} 

printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp); 
fscanf(ZMU_Init_fd, "%s %s", key_tmp, (char *)value_tmp); 
printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp); 

當我運行我得到:

key tmp is y? value tmp is 1 

那麼它出現segfaults。當我改變獲得「W」的代碼設置zmu.cfg文件的大小爲0,我得到:

key tmp is y? value tmp is 1 
key tmp is y? value tmp is 1 

沒有段錯誤......有趣的是,一旦該文件是0字節,我可以改變訪問回「r」它不再segfaults,我得到:

key tmp is y? value tmp is 1 
key tmp is y? value tmp is 1 

我相信這與fscanf的工作方式有關。掃描時,fscanf會從文件中刪除該行嗎?我所要做的就是從文本文件中獲取鍵值對。我不認爲我可以使用fread因爲鍵不總是有相同的大小。我不想修改文件,有什麼想法?

zmu.cfg看起來是這樣的:

MessageNum= message50 
MsgInitOne= 0x01 
MsgInitTwo= 0x04 
MsgInitThree= 0x01 

MessageNum= message50 
VarOne= 0x02 
VarTwo= 0x01 

MessageNum= message50 
MsgValOne= 0x01 
MsgValTwo= 0x04 
MsgValThree= 0x02 

回答

1

這裏使用它之前,你還沒有初始化key_tmp

printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp); 

您正在向fscanf傳遞錯誤參數。鑄造value_tmpchar*不能使它保存一個字符串。

fscanf(ZMU_Init_fd, "%s %s", key_tmp, (char *)value_tmp); 

如果文件中包含一個整數,使用方法:

fscanf(ZMU_Init_fd, "%s %d", key_tmp, &value_tmp); 

如果文件中包含一個字符串,確保value_tmp是大到足以容納數據的字符串。

char value_temp[1000]; 

,然後,使用:

fscanf(ZMU_Init_fd, "%s %s", key_tmp, value_tmp); 
+0

MessageNum的鍵值只是將來可能編輯此文件的人員的佔位符,幾乎就像評論一樣。 我真的只關心十六進制值。我想我可以這樣做:fscanf(ZMU_Init_fd,「%s%s」,key_tmp,key_tmp);我會更新並重新發布。 –

+0

如果你這樣做,你很可能會得到被該值覆蓋的密鑰。 –

+0

對於第一行,我打算取消鍵值對,但問題肯定不是傳遞value_tmp的地址。我的問題是否因爲我沒有初始化值而被拒絕投票?投下的票數極大地阻礙了我對SO的提問。 –

0

你有你的第一個電話體驗未定義行爲到:

printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp); 

無論key_tmpvalue_tmp被初始化爲任意值。嘗試訪問未初始化的值後,所有投注都將關閉。你的代碼可能會給你一些輸出,或者它可能會出現段錯誤 - 你正在經歷未定義的行爲 - 任何事情都可能發生。

此外,如果您正在閱讀的value_tmpint,你fscanf格式字符串應該是:

fscanf(ZMU_Init_fd, "%s %d", key_tmp, &value_tmp); 
+0

我真的不關心第一個printf上的值,我只是將它們打印出來看看它們是否發生了變化。 –

+0

@MeganB進入**未定義行爲的領域後**您的代碼不能依賴任何東西。你可能會得到一個合適的價值,它可能完成沒有問題,或者它可能會段錯誤和崩潰。從那一點開始你的代碼的操作只是** undefined **。 –

+0

好點,我應該初始化任何一種方式。未來我會迴避這種事情。 –

0

耶!我改變了最後幾行這樣:

fscanf(ZMU_Init_fd, "%s %s", key_tmp, key_tmp); 
printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp); 
fscanf(ZMU_Init_fd, "%s %x", key_tmp, &key_tmp); 
printf("key tmp is %s, value tmp is %d\n", key_tmp, value_tmp); 

,我也得到:

key tmp is message50 value tmp is 8388608 
key tmp is MsgInitOne value tmp is 1 

感謝您看我的代碼,沒想到,我需要通過key_tmp的地址爲FSCANF%I因爲我不需要爲%s。