2011-11-15 41 views
2

我有一個ASCII二進制文件看起來是這樣的:尋求到線路號C

00010110001001000110011001000111 
01011000011100001010100001001000 
11110001011010000010010101111010 
00000000000000000000000000000000 
01011010101000010001010101110000 

每一行有32個字符(因此它是一個長度爲33的與\n)。我試圖找到我的文件指針,指向0x0行(上例中的第4行)後面的行。

我做了如下。首先,我計算了文件中有多少行。所以在這種情況下5。我還在持有0x0一行的行上保留了一個索引。所以4在這種情況下。我通過33它返回字符0x0後的第一個號碼是(我要補充一個1,因爲這實際上是在0x0行結束返回\n乘以4

在那之後,我只是用fseek。但是,它不工作什麼是錯在這裏這裏是我的代碼:?!

int bytes = 33 * c; 
fseek(fp, bytes+1, SEEK_SET); 
char test[34]; 
printf("HERE: '%s'", fgets(test, 34, fp)); 

感謝

+3

包含零線的行號是第3行,而不是第4行。 –

+0

不是。我得到'(null)' – darksky

+6

任何時候當你說「它不工作」或「我得到一個錯誤」時,你需要正確解釋**這些短語的含義。確切地*如何*是「不工作」?如果這是一個錯誤,** exact **錯誤信息是什麼?請記住,我們無法從這裏看到您的屏幕,我們唯一需要做的就是您在問題中輸入的內容。如果你需要幫助解決問題,你必須清楚你實際想要解決的問題。換句話說,幫助我們來幫助你。 :) –

回答

3

不,你需要增加一個在所有的的偏移量。文件中的第一個字符爲0.

如果第二行上的第一個字符爲33(假設行結束確實是換行符,而不是CR/LF組合)。

上第三行第一個字符的偏移66

所以,你的代碼實際上應該是:

int bytes = 33 * c; 
fseek (fp, bytes, SEEK_SET); // no "+1" here. 
char test[34]; 
printf ("HERE: '%s'", fgets(test, 34, fp)); 

這裏的成績單顯示,在行動:

pax$ cat qq.in 
00010110001001000110011001000111 
01011000011100001010100001001000 
11110001011010000010010101111010 
00000000000000000000000000000000 
11110000111100001111000011110000 

pax$ cat qq.c 
#include <stdio.h> 

int main (void) { 
    char test[34]; 
    int c = 4; 
    FILE *fp = fopen ("qq.in", "r"); 

    int bytes = 33 * c; 
    fseek (fp, bytes, SEEK_SET); 
    printf("HERE: %s", fgets(test, 34, fp)); 

    fclose (fp); 
    return 0; 
} 

pax$ gcc -o qq qq.c ; ./qq 
HERE: 11110000111100001111000011110000 

試試看這個代碼我在你的環境中,看看會發生什麼。如果你沒有得到正確的數據,那麼你的代碼和你的輸入文件之間會有某種不匹配。

您還沒有指定你在什麼平臺,因此可能是,你實際上是在線條,而不是僅僅\n結束還有\r\n。您也可能以錯誤的模式打開它(儘管這通常只在Windows上很重要)。

對文件進行轉儲以驗證其內容是個不錯的主意。例如,在一個UNIXy系統:

pax$ od -xcb qq.in 

0000000 3030 3130 3130 3031 3030 3031 3130 3030 
      0 0 0 1 0 1 1 0 0 0 1 0 0 1 0 0 
     060 060 060 061 060 061 061 060 060 060 061 060 060 061 060 060 
0000020 3130 3031 3130 3031 3130 3030 3130 3131 
      0 1 1 0 0 1 1 0 0 1 0 0 0 1 1 1 
     060 061 061 060 060 061 061 060 060 061 060 060 060 061 061 061 
0000040 300a 3031 3131 3030 3030 3131 3031 3030 
     \n 0 1 0 1 1 0 0 0 0 1 1 1 0 0 0 
     012 060 061 060 061 061 060 060 060 060 061 061 061 060 060 060 
: 
<< Unnecessary Detail Removed >> 
: 
0000240 3030 3030 000a 
      0 0 0 0 \n 
     060 060 060 060 012 
0000245 

另外,你可能想使用它們之前打印出來的cbytes值。 fgets函數只會在有錯誤時返回NULL,或者在讀取任何數據之前到達EOF。所以,如果你得到NULL作爲返回值,或者你已經在文件的末尾找到(可能),或者你遇到了一個錯誤(有點不太可能,但不是不可能)。

+0

這樣做(刪除-1)在'printf'語句中返回'null' .. – darksky

+2

@Nayefc:那麼你的輸入文件不是你的想法。 – paxdiablo

+0

是的。這是txt文件,完全符合你的要求。最後你有額外的線路嗎?我也使用'fseek(fp,0,SEEK_SET)'來重置我的文件指針。 – darksky