C言語でテキストファイルの行数を数える方法
1. fgets関数を使う方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <stdio.h> #define BUF_SIZE 256 int main(void) { FILE *fp; char buf[BUF_SIZE]; int line = 0; if ((fp = fopen("example.txt", "r")) == NULL) { return -1; } while (fgets(buf, BUF_SIZE, fp) != NULL) { line++; } printf("%d\n", line); return 0; } |
fgets関数は1行ごとに読み込むので、読みこんだ回数 == 行数としてカウントしていくもの。
読み込みに失敗するとfgets関数はNULL
を返すので、それを利用してEOFまで読み込みます。
インターネットではこの方法がよく載っていますが、必ず正しい行数がカウントできるとは限りません。
fgets関数はバッファのサイズを超えて読み込まないので、1行がバッファのサイズを超えると行数を正しくカウントできなくなってしまいます。
fgets関数を使う方法は実行速度が速いので、1行の長さがはっきりと分かる場合は使ってもいいと思います。
2. fgetc関数を使う方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <stdio.h> int main(void) { FILE *fp; int c; int line = 0; if ((fp = fopen("example.txt", "r")) == NULL) { return -1; } while ((c = fgetc(fp)) != EOF) { if (c == '\n') line++; } printf("%d\n", line); return 0; } |
fgetc関数で改行文字を1バイトづつカウントしていく方法です。
行数を正しくカウントできますが、実行速度が遅いです。
3. fread関数を使う方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <stdio.h> #define BUF_SIZE 256 int main(void) { FILE *fp; char buf[BUF_SIZE]; size_t read_size; int line = 0; if ((fp = fopen("example.txt", "r")) == NULL) { return -1; } while ((read_size = fread(buf, 1, BUF_SIZE, fp)) > 0) { for (size_t i = 0; i < read_size; i++) { if (buf[i] == '\n') line++; } } printf("%d\n", line); return 0; } |
fread関数で一度バッファに読み込み、そこから改行文字をカウントしていく方法です。
バッファの終端が\0
ではない点に注意しなければいけません。
fread関数は読み込んだデータの数を返すので、そこからバッファの文字数が分かります。
実行結果と実行速度
テストデータとしてexample.txt(4906788バイト、30172行)を用意して計測。
gcc 6.2.0でコンパイラオプションは-std=c99
のみ指定してコンパイル。
実行結果
fgets | fgetc | fread |
41952 | 30172 | 30172 |
1行の長さがバッファを超えたのでfgets関数を使ったプログラムは余計に行数をカウントしてしまいました。
実行速度
単位:秒
fgets | fgetc | fread |
0.004 | 0.064 | 0.024 |
fgets関数を使ったプログラムが1番速いです。
実行結果は間違っていましたが。