我有一个ASCII二进制文件,看起来像:
00010110001001000110011001000111
01011000011100001010100001001000
11110001011010000010010101111010
00000000000000000000000000000000
01011010101000010001010101110000
每行有32个字符(所以长度为33,\n
)。我试图找到我的文件指针,指向0x0
行之后的行(上例中的第4行)。
我做的如下。首先,我计算了文件中有多少行。所以5
就是这种情况。我还在保持0x0
线的线上保留了一个索引。所以4
就是这种情况。我将4
乘以33
,它返回0x0
之后第一个数字的哪个字符(我必须添加1,因为这实际上会返回\n
的结尾。 0x0
行。
之后,我只使用了fseek
。但是,它不起作用。这有什么不对?这是我的代码:
int bytes = 33 * c;
fseek(fp, bytes+1, SEEK_SET);
char test[34];
printf("HERE: '%s'", fgets(test, 34, fp));
谢谢!
答案 0 :(得分: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
在您的环境中尝试该代码,看看会发生什么。如果您没有获得正确的数据,那么您的代码和某种输入文件之间就会不匹配。
您尚未指定自己所在的平台,因此 可能是您在行尾的实际\r\n
而非\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
此外,您可能希望在使用之前打印出c
和bytes
的值。只有在出现错误或在读取任何数据之前达到EOF时,fgets
函数才会返回NULL。
所以,如果你得到NULL作为返回值,要么你已经寻找超出文件末尾(可能),要么你遇到了错误(有些不太可能但不是不可能)。