2016-01-19 52 views
2

1)在C中有一种方法可以找到我们从文件中读取的行的行号。有没有办法找到从文件中读取的当前行的行号?

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

+0

我假设你的意思是在每行中寻找'\ n',而不是EOF。不,这是唯一的方法。 –

回答

3

1)在C语言中,我们可以找到我们从文件中读取的行的行号。

除非你从文件的开始处开始计算行数。除非文件本身中有信息告诉你,否则你不能仅仅将自己定位在文件中,并知道你正在处理的是哪一行文本,或者你已经通过文件的先前传递创建了一个排序索引。通常的做法是在处理文件中的行时累计行数。

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

不可以。您必须遍历整个文件并计算行数。任何外部工具(如wc)都在这样做。您需要了解不同的行结束样式。根据您使用什么函数来读取文件,您可能会也可能不会自动换行。

0

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

您可以使用popen用命令

wc -l filename 

或命令

sed -n '$=' loop.c 

要知道更多一起,怎么读第popen功能被使用。这里是一个例子

#include<stdio.h> 
#include<stdlib.h> 

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); 
} 
+0

这是做什么用的?它是否给你正在阅读的行?我可以在C代码中使用它吗? – Brandon

+0

@Brandon,看到更新.. – Haris

+0

我做了,只是有点糊涂你的意思,然后使用该命令。你是否在讨论在命令行中使用它?我想知道如何通过代码本身找到它。 – Brandon

2

你可以计算行结束,因为他们经过。当然,线路的结局取决于平台。 UNIX使用\ n,Mac使用\ r(或至少他们曾经使用过),Windows使用\ r \ n。

你可以看一下wc的源代码(一个标准的UNIX工具,用于对文件中的行,字符等进行计数)。这里是OpenBSD's wc source

0

1)有没有用C的方式,我们可以找到一个线 ,我们从文件中读取的行号。

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

#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') 
相关问题