2016-01-19 74 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') 
相關問題