我在一些示例文本文件上测试了这个函数,以确保它按预期工作。
#include <stdio.h>
#include <time.h>
#define BUF 100
int main(){
FILE *fp = fopen("my_huge_file.txt","r");
char str[BUF];
int count=0;
while( (fgets(str, BUF, fp)) != NULL ){
for (int i = 0; i<BUF;i++){
if (str[i] == 'A')
count++;
}
}
printf("We had %d 'A'sn",count);
}
使用time ./a.out
打印运行此操作:
We had 420538682 'A's real 0m31.267s user 0m28.590s sys 0m2.531s
然后我使用time tr -cd A < my_huge_file.txt | wc -c
并返回:
420538233 real 0m13.611s user 0m10.688s sys 0m3.297s
我还使用了python的计数方法time count.py
:
c = 0
with open("my_huge_file.txt", 'r') as fp:
for line in fp:
c += line.count('A')
print(c)
420538233 real 0m33.073s user 0m30.232s sys 0m2.650s
我不知道如何调查这种差异。tr和python的计数返回420538233。C函数返回420538682。
尝试更改:
for (int i = 0; i<BUF;i++){
至
for (int i = 0; i<BUF && str[i] ;i++){
看看你是否得到了不同的输出。。。。
没有理由用fgets
使代码复杂化。(问题是fgets
读取一行,只填充缓冲区的一部分,但您正在计算缓冲区中的所有内容,包括不是来自输入的值。(一次只读取一个字符:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
int c;
int count=0;
FILE *fp = argc > 1 ? fopen(argv[1], "r") : stdin;
if( fp == NULL ){
perror(argv[1]);
exit(EXIT_FAILURE);
}
while( (c = fgetc(fp)) != EOF ){
if( c == 'A' ){
count += 1;
}
}
printf("We had %d 'A'sn", count);
return 0;
}