获取ASCII文件行的最快方法是什么?
答案 0 :(得分:19)
通常使用fgets
读取C中的文件。您也可以使用scanf("%[^\n]")
,但很多人在阅读代码时可能会发现令人困惑和异国情调。
编辑:另一方面,如果你真的想要计算行数,scanf
方法的略微修改版本可以很好地工作:
while (EOF != (scanf("%*[^\n]"), scanf("%*c")))
++lines;
这样做的好处是,在每次转换中使用'*',scanf
会读取并匹配输入,但不会对结果执行任何操作。这意味着我们不必在大缓冲区上浪费内存来保存我们不关心的行的内容(并且仍然有可能获得比这更大的行,所以我们的计数结果错了除非我们甚至更多工作以确定我们读取的输入是否以换行符结束。)
不幸的是,我们必须将scanf
分成两部分。转换失败时scanf
停止扫描,如果输入包含空行(两个连续的换行符),我们预计第一次转换将失败。然而,即使失败了,我们也希望第二次转换发生,读取下一个换行符并继续下一行。因此,我们尝试第一次转换“吃掉”该行的内容,然后进行%c
转换以读取换行符(我们真正关心的部分)。我们继续执行这两个操作,直到第二次调用scanf
返回EOF
(通常位于文件的末尾,尽管在读取错误的情况下也会发生这种情况)。
Edit2:当然,还有另一种可能性(至少可以说是)更简单易懂:
int ch;
while (EOF != (ch=getchar()))
if (ch=='\n')
++lines;
有些人发现违反直觉的唯一部分是ch
必须被定义为int
,而不是char
才能使代码生效正确。
答案 1 :(得分:4)
这是一个基于fgetc()的解决方案,它适用于任何长度的行,不需要你分配缓冲区。
#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;
}
答案 2 :(得分:2)
也许我错过了什么,但为什么不简单:
#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);
}
答案 3 :(得分:2)
常见,为什么要比较所有角色?这很慢。在10MB文件中它是~3s。
解决方案更快。
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;
}
答案 4 :(得分:1)
这个怎么样?
#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;
}