1)在C中有一種方法可以找到我們從文件中讀取的行的行號。有沒有辦法找到從文件中讀取的當前行的行號?
2)我也想知道是否有另一種方法來找出文件中的行總數,而不是創建一個循環,在每行中尋找EOF
,直到達到結尾。
1)在C中有一種方法可以找到我們從文件中讀取的行的行號。有沒有辦法找到從文件中讀取的當前行的行號?
2)我也想知道是否有另一種方法來找出文件中的行總數,而不是創建一個循環,在每行中尋找EOF
,直到達到結尾。
1)在C語言中,我們可以找到我們從文件中讀取的行的行號。
除非你從文件的開始處開始計算行數。除非文件本身中有信息告訴你,否則你不能僅僅將自己定位在文件中,並知道你正在處理的是哪一行文本,或者你已經通過文件的先前傳遞創建了一個排序索引。通常的做法是在處理文件中的行時累計行數。
2)我也想知道是否有另一種方法來找出文件中的行數,而不是通過創建一個循環來查找每行中的EOF,直到達到最終。
不可以。您必須遍歷整個文件並計算行數。任何外部工具(如wc
)都在這樣做。您需要了解不同的行結束樣式。根據您使用什麼函數來讀取文件,您可能會也可能不會自動換行。
我還想知道是否有另一種方法來找出文件中的行數,而不是創建一個在每行中查找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);
}
你可以計算行結束,因爲他們經過。當然,線路的結局取決於平臺。 UNIX使用\ n,Mac使用\ r(或至少他們曾經使用過),Windows使用\ r \ n。
你可以看一下wc的源代碼(一個標準的UNIX工具,用於對文件中的行,字符等進行計數)。這裏是OpenBSD's wc source。
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')
我假設你的意思是在每行中尋找'\ n',而不是EOF。不,這是唯一的方法。 –