• 検索結果がありません。

file"a" file"b" fp = fopen("a", "r"); while(fgets(line, BUFSIZ, fp)) {... fclose(fp); fp = fopen("b", "r"); while(fgets(line, BUFSIZ, fp)) {... fclose

N/A
N/A
Protected

Academic year: 2021

シェア "file"a" file"b" fp = fopen("a", "r"); while(fgets(line, BUFSIZ, fp)) {... fclose(fp); fp = fopen("b", "r"); while(fgets(line, BUFSIZ, fp)) {... fclose"

Copied!
25
0
0

読み込み中.... (全文を見る)

全文

(1)

I117

9

)テキストファイル(その

2

知念

北陸先端科学技術大学院大学 情報科学研究科

School of Information Science,

(2)

複数ファイル読み込み(直列)

file"A" file"B" fp = fopen("A", "r"); while(fgets(line, BUFSIZ, fp)) { ... } fclose(fp); fp = fopen("B", "r"); while(fgets(line, BUFSIZ, fp)) { ... } fclose(fp); ...

(3)

ループで複数ファイルを扱う

重複をさけ、繰り返しをループにする ファイル名以外は同じ ¦ ファイル名は配列に蓄える for(i=0;i<filelistnum;i++) { fp = fopen(flist[i],"r"); while(fgets(line, BUFSIZ, fp)) { ... } fclose(fp); }

(4)

argc, argv

プログラムへ引数を与える枠組多くのプログラムで利 用されている

int main(int argc, char *argv[]) { ...

argc には引数の数

argv には引数が入っている

¦ argv[0] はプログラムの名前 ファイル名を渡すのに便利

(5)

argc, argv

(cont .)

引数を印刷するだけのプログラム

#include <stdio.h>

int main(int argc, char *argv[]) { int i; for(i=0;i<argc;i++) printf("%d %s\n", i, argv[i]); } % ./a.out A B 0 ./a.out 1 A

(6)

argc, argv

(cont .)

合成すると... argv[0] はスキップ

#include <stdio.h>

int main(int argc, char *argv[]) {

char line[BUFSIZ]; int i; FILE *fp; for(i=1;i<argc;i++) { fp = fopen(argv[i],"r"); while(fgets(line, BUFSIZ, fp)) { ... } fclose(fp); } }

(7)

複数ファイル行数計算

#include <stdio.h>

int main(int argc, char *argv[]) { char line[BUFSIZ]; FILE *fp; int i, lc=0; for(i=1;i<argc;i++) { fp = fopen(argv[i],"r"); while(fgets(line, BUFSIZ, fp)) { lc++; } fclose(fp); } printf("%d\n",lc);

(8)

複数ファイル行数計算

(cont .) 実行例、wcとの比較 % ./a.out xargcv.c nlc01.c 21 % wc xargcv.c nlc01.c 8 18 138 xargcv.c 13 30 243 nlc01.c 21 48 381 total 処理を明解にするため、関数に分離する

(9)

複数ファイル行数計算

(cont .)

指示されたファイルの行数を数える

#include <stdio.h>

int linecount(char *fname) { char line[BUFSIZ]; FILE *fp; int lc=0; fp = fopen(fname,"r"); while(fgets(line, BUFSIZ, fp)) { lc++; } fclose(fp); return lc; }

(10)

複数ファイル行数計算

(cont .)

main は linecount を呼び出し、合計を求める

int main(int argc, char *argv[]) { int i, lc, sum=0; for(i=1;i<argc;i++) { lc = linecount(argv[i]); sum += lc; } printf("%d\n",sum); }

(11)

複数ファイル行数計算

(cont .) % ./a.out *.c 40 % wc *.c 12 30 245 nlc01.c 20 46 357 nlc01b.c 8 18 138 xargcv.c 40 94 740 total

(12)

エラーハンドリング

fopen の失敗 fp = fopen(fname,"r"); if(fp==NULL) return -1; linecount の失敗 lc = linecount(argv[i]); if(lc<0) continue;

(13)

エラーハンドリング

(cont .)

シンプルなメッセージで十分

fp = fopen(fname,"r"); if(fp==NULL) {

fprintf(stderr,

"can not open file %s\n", fname); return -1;

}

% ./a.out ignorefilename *.c

can not open file ignorefilename 109

(14)

エラーハンドリング

(cont .)

ちなみに、wc も似たようもの

% wc ignorefilename *.c

wc: ignorefilename: No such file or directory

12 30 245 nlc01.c 20 46 357 nlc01b.c 34 55 455 nlc01c.c 35 62 507 nlc01d.c 8 18 138 xargcv.c 109 211 1702 total

(15)

並列複数ファイル読み込み

同時に複数ファイルを扱う ファイル数分情報を確保する typedef struct { char *fname; FILE *fp; char line[BUFSIZ]; int lc; int reach_eof; } lcparam; file"B" file"C" file"D" file"A" file"E"

(16)

並列複数ファイル読み込み

(cont .)

全ファイルを読み終るまで繰り返す

open read close

ファイル長がバラバラなので、最後に達したかどうか 判定が必要

(17)

並列複数ファイル読み込み

(cont .) lcparam *lclist; lclist = (lcparam*)malloc( sizeof(lcparam)*(argc)); for(i=1;i<argc;i++) { lc = openfile(&lclist[i], argv[i]); if(lc<0) { continue; } }

(18)

do {

/* process reading */ for(i=1;i<argc;i++) {

lc = linecount(&lclist[i]); }

/* check all file was read */ e = 0; for(i=1;i<argc;i++) { if(lclist[i].reach_eof>0) { e++; } } } while(e<argc-1);

(19)

並列複数ファイル読み込み

(cont .) sum = 0; for(i=1;i<argc;i++) { printf("%s %d\n", lclist[i].fname, lclist[i].lc); sum += lclist[i].lc; if(lclist[i].fp) { fclose(lclist[i].fp); } } printf("total %d\n",sum);

(20)

並列複数ファイル読み込み

(cont .) int openfile(lcparam *lcp, char *fname) { FILE *fp; lcp->reach_eof = -1; lcp->fp = NULL; lcp->lc = 0; lcp->fname = strdup(fname); fp = fopen(fname,"r"); if(fp==NULL) { fprintf(stderr,

(21)

並列複数ファイル読み込み

(cont .) lcp->reach_eof = 1; return -1; } lcp->fp = fp; lcp->reach_eof = 0; return 0; } 失敗した場合には -1、成功したら 0 を返す

(22)

並列複数ファイル読み込み

(cont .) int linecount(lcparam *lcp) { if(lcp->reach_eof!=0) { return -1; } if(fgets(lcp->line,BUFSIZ,lcp->fp)){ lcp->lc++; return 0; } lcp->reach_eof = 1; return 1; }

(23)

並列複数ファイル読み込み

(cont .) 結果 % ./a.out *.c nlc01.c 12 nlc01b.c 20 nlc01c.c 34 nlc01d.c 35 plc01.c 90 plc01b.c 87 xargcv.c 8 total 286

(24)

演習

1) 直列複数ファイル行数計上のプログラムで各ファ イルの行数を表示するよう改造せよ★ (BUFSIZより)長い行は考慮しなくて良い 2) 同様に各ファイルのバイト数を表示するよう改造 せよ★ 3) 同様に各ファイルの単語数を表示するよう改造せ よ★★ プログラム wc と同様の出力にせよ

(25)

演習

(cont .)

4) 並列複数ファイル読み込みの別実装を作れ★

個々のファイルを読み終るとすぐに close を実施 する

参照

関連したドキュメント

Program’s name number 1 02:30 203°F 300G. 300G

Here, instead of considering an instance I and trying to directly develop a feasible solution for the P, G ∗ |prec; c ij dπ k , π l 1; p i 1|C max problem, we consider a

[1] Feireisl E., Petzeltov´ a H., Convergence to a ground state as a threshold phenomenon in nonlinear parabolic equations, Differential Integral Equations 10 (1997), 181–196..

We find the criteria for the solvability of the operator equation AX − XB = C, where A, B , and C are unbounded operators, and use the result to show existence and regularity

(The Elliott-Halberstam conjecture does allow one to take B = 2 in (1.39), and therefore leads to small improve- ments in Huxley’s results, which for r ≥ 2 are weaker than the result

[r]

Shi, “The essential norm of a composition operator on the Bloch space in polydiscs,” Chinese Journal of Contemporary Mathematics, vol. Chen, “Weighted composition operators from Fp,

We study the classical invariant theory of the B´ ezoutiant R(A, B) of a pair of binary forms A, B.. We also describe a ‘generic reduc- tion formula’ which recovers B from R(A, B)