哪种方法是获取ASCII文件行数最快的方法?
通常使用 fgets
在 C 中读取文件。你也可以使用 scanf("%[^\n]")
,但是很多人读这段代码时可能会感到困惑和陌生。
编辑:另一方面,如果你只想计算行数,稍微修改一下 scanf
的方法也可以非常好地完成:
while (EOF != (scanf("%*[^\n]"), scanf("%*c")))
++lines;
这样做的好处是,在每次转换中都有一个 '*',scanf
读取并匹配输入,但不对结果进行任何操作。这意味着我们不必浪费内存来存储我们不关心的行的内容(并且仍然有机会获得比那更大的行,因此除非我们进行了更多的工作以确定我们读取的输入是否以换行符结尾,否则我们的计数会出错)。scanf
分成两部分。当转换失败时,scanf
停止扫描,并且如果输入包含空行(两个连续的换行符),我们希望第一项转换失败。即使失败了,我们也希望第二个转换发生,以读取下一个换行符并继续下一行。因此,我们尝试进行第一个转换来“吃掉”行的内容,然后进行 %c
转换以读取换行符(我们真正关心的部分)。我们继续执行这两个操作,直到第二个 scanf
调用返回 EOF
(通常在文件末尾,但也可能在读取错误的情况下发生)。int ch;
while (EOF != (ch=getchar()))
if (ch=='\n')
++lines;
唯一一点有些令人感到不直观的是,ch
必须定义为int
而不是char
才能使代码正常工作。#include <stdio.h>
int main()
{
FILE *fp = stdin; /* or use fopen to open a file */
int c; /* Nb. int (not char) for the EOF */
unsigned long newline_count = 0;
/* count the newline characters */
while ( (c=fgetc(fp)) != EOF ) {
if ( c == '\n' )
newline_count++;
}
printf("%lu newline characters\n", newline_count);
return 0;
}
#include <stdio.h>
int main(void) {
int n = 0;
int c;
while ((c = getchar()) != EOF) {
if (c == '\n')
++n;
}
printf("%d\n", n);
}
如果您想计算部分行(即 [^\n]EOF):
#include <stdio.h>
int main(void) {
int n = 0;
int pc = EOF;
int c;
while ((c = getchar()) != EOF) {
if (c == '\n')
++n;
pc = c;
}
if (pc != EOF && pc != '\n')
++n;
printf("%d\n", n);
}
getchar()
答案,因为它处理了最后一行没有以 '\n'
结尾的情况。建议进行轻微简化:int pc = '\n'; while (..) { ...} if (pc != '\n') ++n;
- chux - Reinstate Monica为什么要比较所有字符呢?这样会非常慢。在10MB的文件中,需要大约3秒钟。
下面是更快的解决方案。
unsigned long count_lines_of_file(char *file_patch) {
FILE *fp = fopen(file_patch, "r");
unsigned long line_count = 0;
if(fp == NULL){
return 0;
}
while ( fgetline(fp) )
line_count++;
fclose(fp);
return line_count;
}
fgetline()
不在C99或C11规范中。 - chux - Reinstate Monica这个怎么样?
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 4096
int main(int argc, char** argv)
{
int count;
int bytes;
FILE* f;
char buffer[BUFFER_SIZE + 1];
char* ptr;
if (argc != 2 || !(f = fopen(argv[1], "r")))
{
return -1;
}
count = 0;
while(!feof(f))
{
bytes = fread(buffer, sizeof(char), BUFFER_SIZE, f);
if (bytes <= 0)
{
return -1;
}
buffer[bytes] = '\0';
for (ptr = buffer; ptr; ptr = strchr(ptr, '\n'))
{
++count;
++ptr;
}
}
fclose(f);
printf("%d\n", count - 1);
return 0;
}
BUFFER_SIZE
的倍数的文件上(包括空文件,如@vlabrecque所指出的)以-1
退出。 - chux - Reinstate Monica