使用C查找文本文件中的行号

使用C查找文本文件中的行号,c,fseek,C,Fseek,我有一个ASCII二进制文件,看起来像: 00010110001001000110011001000111 01011000011100001010100001001000 11110001011010000010010101111010 00000000000000000000000000000000 01011010101000010001010101110000 每行有32个字符(因此长度为33,带有\n)。我试图查找指向0x0行(上例中的第4行)后面的行的文件指针 我所做的如下。首先,

我有一个ASCII二进制文件,看起来像:

00010110001001000110011001000111
01011000011100001010100001001000
11110001011010000010010101111010
00000000000000000000000000000000
01011010101000010001010101110000
每行有32个字符(因此长度为33,带有
\n
)。我试图查找指向
0x0
行(上例中的第4行)后面的行的文件指针

我所做的如下。首先,我计算了文件中有多少行。所以在这种情况下
5
。我还在保存
0x0
行的行上保留了一个索引。所以在这种情况下
4
。我将
4
乘以
33
,返回
0x0
后面的第一个数字是哪个字符(我必须加上1,因为这实际上返回
0x0
行末尾的
\n

之后,我只使用了
fseek
。但是,它不起作用。这里出了什么问题?这是我的代码:

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

不,您不必添加任何字符。文件中第一个字符的偏移量为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
此外,在使用
c
bytes
之前,您可能需要打印出它们的值。
fgets
函数仅在出现错误或在读取任何数据之前达到EOF时才会返回NULL


因此,如果返回值为NULL,则可能是查找文件结尾以外的内容(可能),也可能是遇到了错误(可能性较小,但并非不可能)。

保留零行的行号是第3行,而不是第4行。只要你说“它不起作用”或“我出错”,你需要准确地解释这些短语的意思。它到底是如何“不起作用”的?如果是错误,确切的错误信息是什么?请记住,我们从这里看不到您的屏幕,我们唯一要做的是您在问题中键入的内容。如果您想帮助解决问题,您必须清楚您实际要解决的问题是什么。换句话说,请帮助我们帮助您。:@Russel,这取决于你是否考虑顶部的行是第一个或第0个:-)第一行的第一个字节是文件偏移0。如果你的算法没有给你第一行的偏移量为零,那么它就被破坏了。@DavidSchwartz我该如何打印第一行的偏移量?@Nayefc:那么你的输入文件就不是你所想的。它是。它是一个txt文件,与您拥有的内容完全匹配。末尾有多余的一行吗?我还使用
fseek(fp,0,SEEK\u SET)
重置了我的文件指针,以防万一。@Nayefc:first things first。在我的
qq.in
qq.c
文件中键入,编译它们并运行。这会告诉你你的环境是否被破坏了。这是可能的,但我怀疑。下一步,打印出输入文件的
c
bytes
的值以及
od
。然后创建一个完整的、可编译的、尽可能小的程序,该程序仍然表现出这种错误行为。然后我们就可以开始了。我正在运行Mac,所以我相信\r不存在。它存在,但在现代MacOS的文本文件中没有使用。我假设您运行的不是OSX之前的版本,该版本的行尾是
\r
(来自memeory)。但这只是一个旁白,您需要遵循上面概述的步骤。
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