2014-02-26 112 views
1

我試圖讀取txt文件中的數據。 txt文件有多個條目,每個條目佔據一個新的行,並且每個條目具有由一些符號(比如空格'')分隔的可變長度的十六進制字節數據。樣品txt文件看起來像下面fscanf閱讀空間分隔數據,直到返回

e4 e2 e2 e1 ff\n 
f2 a2 22 34\n 
ff ee dd\n 

在循環中使用的scanf(FP,「%2X」,緩衝液+偏移量),我試圖每個字節加載到字節緩衝器中,直到每條線的端,標誌着一個完整的記錄。主要的問題是檢測換行符,因爲scanf完全忽略它並跳到下一行。我的原始代碼是

do{ 
    counter=fscanf(datain,"%2x",buffer1+offset); 
    fprintf(stdout,"%#2x ",buffer1[offset]); 
    offset+=counter; 
}while(!feof(datain)); 

回答

2

一種替代,並且通常更簡單的方式做這樣的工作的輸出是與fgets()getline()讀取整個行,然後再處理使用sscanf()行的符號。在許多方面,這類似於目前的方案,但你需要能夠通過串進步,所以%n轉換規範常常表現出樂於助人的位置:

while (fgets(line, sizeof(line), datain) != 0) 
{ 
    int line_offset = 0; 
    int new_offset; 
    while (sscanf(line + line_offset, "%2x%n", &buffer1[offset], &new_offset) == 1) 
    { 
     printf("%#.2x ", buffer1[offset]); 
     offset++; 
     line_offset += new_offset; 
    } 
} 

%n轉換不計從sscanf()返回。

請注意,這可以避免在另一個answer中看到的其他一些問題。當沒有行要讀取時,它不會嘗試處理數據,並且在沒有剩下任何行時不會嘗試處理數據。

另外,一次讀取一行的好處之一是,當您可以將錯誤發生的整個上下文(行)提供給錯誤報告時,錯誤報告通常會更容易/更好,而不會陷入在成功轉換數量不確定的情況下排隊。如果在該行的第六個字段中存在錯誤字符,則可以顯示前五個字段以及錯誤很簡單的位置。

0

通過在每個十六進制說明符後附加%c,我可以從流中提取空格和換行符。通過測試這個角色,我可以知道一條新線路已經到達。

do{ 
    counter=fscanf(datain,"%2x%c",buffer1+offset,&followsymbol); 
    fprintf(stdout,"Counter:%i\n",counter); 
    if (counter==2) 
     {fprintf(stdout,"data:%5x\tfollowsymbol:%5x\n",buffer1[offset],followsymbol); 
      offset+=1; 
     } 
    if(followsymbol==0x0a && counter==2) 
      printf("a nl symbol has been detected\n"); 
}while(!feof(datain)); 

從終端

Counter:2 
data:ffffffe4 followsymbol: 20 
Counter:2 
data:ffffffe2 followsymbol: 20 
Counter:2 
data:ffffffe2 followsymbol: 20 
Counter:2 
data:ffffffe1 followsymbol: 20 
Counter:2 
data:ffffffff followsymbol: a 
a nl symbol has been detected 
Counter:2 
data:fffffff2 followsymbol: 20 
Counter:2 
data:ffffffa2 followsymbol: 20 
Counter:2 
data: 22  followsymbol: 20 
Counter:2 
data: 34  followsymbol: a 
a nl symbol has been detected 
Counter:2 
data:ffffffff followsymbol: 20 
Counter:2 
data:ffffffee followsymbol: 20 
Counter:2 
data:ffffffdd followsymbol: a 
a nl symbol has been detected 
Counter:65535 
+0

爲什麼你對0x0a進行硬編碼,可能更好地使用'\ n'而不是? – t0mm13b

+0

需要'if(counter == 2 && followingymbol == 0x0a)'。否則'followymbol'可能是之前的值,如果'counter'的值爲EOF或者1. – chux

+0

'fscanf(...,「%2x%c」,...,followingymbol);'應該是'fscanf ... ,「%2x%c」,...,&followingymbol);'(missing&) – chux