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

时间:2016-01-19 05:01:57

标签: c file io lines

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

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

4 个答案:

答案 0 :(得分:3)

  

1)在C中是否有办法找到我们从文件中读取的行的行号。

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

  

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

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

您可以将$('.onoffswitch').on('click', '.onoffswitch-label', function(event) { var checkbox = $(this).prev()[0]; event.preventDefault(); bootbox.confirm({ message: "Are you sure ?", closeButton: false, callback: function(result) { if (result) { checkbox.checked = !checkbox.checked; $(checkbox).change(); } } }); }); 与命令

一起使用
popen

或命令

wc -l filename

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

sed -n '$=' loop.c

答案 3 :(得分:0)

  

1)在C中是否有办法找到一条线的行号   我们正在从文件中读取。

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

#include <stdio.h>

#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 <stdio.h>
#include <stdlib.h>
#include <limits.h>  /* 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')