有没有办法找到从文件中读取的当前行的行号?

1)在C中是否有一种方法可以找到我们从文件中读取的行的行号。

2)我还想知道是否有另一种方法可以找出文件中的总行数,而不是通过创建一个循环来查找每行中的EOF ,直到它到达结尾。

1)在C中是否有一种方法可以找到我们从文件中读取的行的行号。

除非您计算文件开头的行,否则不会。 您不能随意将自己定位在文件中并知道您所处的文本行,除非文件本身中有信息告诉您,或者您已通过文件的先前传递创建了排序索引。 通常的方法是在处理文件中的行时累积行数。

2)我还想知道是否有另一种方法可以找出文件中的总行数,而不是通过创建一个循环来查找每行中的EOF,直到它到达结尾。

不可以。您必须遍历整个文件并计算行数。 任何外部工具(例如wc )都是这样做的。 您需要了解不同的行结束样式。 根据您用于阅读文件的function,您可能有也可能没有自动换行。

您可以在行结束时计算行结尾。 当然,线路结尾因平台而异。 UNIX使用\ n,Mac使用\ r \ n(或者至少使用它们),Windows使用\ r \ n。

您可以查看wc的源代码(一个标准文件中的行,字符等的标准UNIX实用程序)。 这是OpenBSD的wc源代码 。

我还想知道是否有另一种方法可以找出文件中的总行数,而不是通过创建一个循环来查找每行中的EOF,直到它到达结尾。

您可以将popen与命令一起使用

 wc -l filename 

或命令

 sed -n '$=' loop.c 

要了解更多信息,请阅读如何使用popenfunction。 这是一个例子

 #include #include int main(void) { FILE* p; int a; char str[10]; p = popen("sed -n '$=' loop.c", "r"); fgets(str, 10, p); a = atoi(str); printf("%d", a); } 

1)在C中是否有一种方法可以找到我们从文件中读取的行的行号。

是的,不是。 正如其他人所说,没有机制,仅通过文件位置,您可以在读取文件时找到您在任何给定时间点读取的行号。 这并不意味着您无法轻松跟踪当前正在阅读的行,并编写条件以应用于任何给定的行。 例如,从文件中读取(或默认为stdin )并跟踪当前以及查找总行数的简单方法可能类似于以下内容:

 #include  #define MAXS 256 int main (int argc, char **argv) { char line[MAXS] = {0}; /* line buffer for fgets */ long long unsigned index = 0; FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; while (fgets (line, MAXS, fp)) { printf (" line[%3llu] : %s", index++ + 1, line); } if (fp != stdin) fclose (fp); printf ("\n total : %llu lines\n\n", index); return 0; } 

使用/输出

 $ ./bin/fgets_min_count dat/captnjack.txt line[ 1] : This is a tale line[ 2] : Of Captain Jack Sparrow line[ 3] : A Pirate So Brave line[ 4] : On the Seven Seas. total : 4 lines 

2)我还想知道是否有另一种方法可以找出文件中的总行数,而不是通过创建一个循环来查找每行中的EOF,直到它到达结尾。

根据文件的大小和您需要计算的行数,最大限度地减少读取次数可以大大提高计数的效率。 由于缺少更好的单词,您可以在单次读取中读取整个文件到缓冲区(对于所有INT_MAX字节或更少的文件)或在有限数量的INT_MAX大小读取中读取,然后只需计算'\n'字符(测试/调整没有'\n'文本(作为第一行,或者没有POSIX行结束的最后一行)。

代码只是稍微长一点来考虑fread的大小限制:

 #include  #include  #include  /* for INT_MAX */ char *read_file_into_buf (char **filebuf, long *fplen, FILE *fp); long buf_lines (char *s, long len); int main (int argc, char **argv) { char *filebuf = NULL; long fplen = 0, nlines = 0; FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; if (!fp) { /* validate file open */ fprintf (stderr, "error: file open failed '%s'\n", argv[1]); return 1; } /* read entire file into filebuf*/ if (!read_file_into_buf (&filebuf, &fplen, fp)) return 1; if (fp != stdin) fclose (fp); nlines = buf_lines (filebuf, fplen); /* count lines */ printf ("\n total : %ld lines read (from '%s')\n\n", nlines, argc > 1 ? argv[1] : "stdin"); free (filebuf); return 0; } /** read file from 'fp' into 'filebuf', update 'fplen'. * memory is allocated for filebuf sufficient to hold * contents of 'fp'. returns pointer to 'filebuf' on * success, NULL otherwise. reads at most INT_MAX bytes * at a time from file. */ char *read_file_into_buf (char **filebuf, long *fplen, FILE *fp) { if (!fp) return NULL; size_t nbytes = 0, readsz = 0; long bytecnt = 0; fseek (fp, 0, SEEK_END); if ((*fplen = ftell (fp)) == -1) { /* get file length */ fprintf (stderr, "error: unable to determine file length.\n"); return NULL; } fseek (fp, 0, SEEK_SET); /* allocate memory for file */ if (!(*filebuf = calloc (*fplen, sizeof **filebuf))) { fprintf (stderr, "error: virtual memory exhausted.\n"); return NULL; } /* read entire file into filebuf reading a * maximum of INT_MAX bytes at a time */ readsz = *fplen > INT_MAX ? INT_MAX : *fplen; while ((nbytes = fread ((*filebuf + bytecnt), sizeof **filebuf, readsz, fp))) { bytecnt += nbytes; if (nbytes != readsz) fprintf (stderr, "warning: short read.\n"); if (bytecnt == *fplen) break; readsz = *fplen - bytecnt > INT_MAX ? INT_MAX : *fplen - bytecnt; } if (bytecnt != *fplen) { fprintf (stderr, "error: file read failed.\n"); return NULL; } return *filebuf; } /** count lines in buffer * (line with non-POSIX line end counted as 1) */ long buf_lines (char *fb, long len) { long i = 0, lns = 0; for (;;) { if (fb[0] == '\n') lns++; if (++i == len) { if (fb[0] != '\n') lns++; return lns; } if (fb[1] == '\n') lns++; if (++i == len) { if (fb[1] != '\n') lns++; return lns; } if (fb[2] == '\n') lns++; if (++i == len) { if (fb[2] != '\n') lns++; return lns; } if (fb[3] == '\n') lns++; if (++i == len) { if (fb[3] != '\n') lns++; return lns; } fb += 4; } } 

使用/输出

 $ ./bin/fread_file_count dat/captnjack.txt total : 4 lines read (from 'dat/captnjack.txt')