- ベストアンサー
【C言語】コマンドライン引数の標準入出力
- コマンドライン引数でファイル名を指定し、標準入出力を扱う方法とは?
- C言語のコマンドライン引数を使用してファイル名を指定し、標準入出力を操作する方法を解説します。
- C言語でコマンドライン引数を使い、標準入出力を扱う方法について詳しく説明します。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
追記。 >本来「すべてのコマンドライン引数を評価し終わるまで、fopenなどの実質的な処理を開始しない方が良い」でしょう。 回答の前半に書いた「引数を評価しながらfopenしちゃうプログラム」で 実行モジュール -o 出力ファイル名1 -b ファイル名 -c ファイル名 -o 出力ファイル名2 -o 出力ファイル名3 って実行したら「中身が空の『出力ファイル名1』が作成されてしまってから、duplicate -o switch!ってエラーが表示されて停止してしまう」と思います。 質問者さんも「エラー表示して止まるんだったら、中身が空の『出力ファイル名1』が作成されない方が良い」と思いませんか? なので「すべてのコマンドライン引数を評価し終わるまで、fopenなどの実質的な処理を開始してはいけない」のです。
その他の回答 (3)
- trapezium
- ベストアンサー率62% (276/442)
> -aの次のコマンドライン引数が、出力ファイル名です。 コードでは -o となってるけど? 別の回答者さんの言うように、fopen() は後回しにした方がいいでしょう。 > for(j=1;j<argc-1;j++){ これだと最後の引数を評価してませんよ? 全てが -o file みたいならいいですが、file が必要ないスイッチがあるとまずくありませんか? FILE * fo = stdout; char * outf = NULL; for(j=1;j<argc;j++){ if(strcmp(argv[j],"-o")==0){ if (++j < argc) { if (outf) { fprintf(stderr, "duplicate -o option\n"); exit(1); } outf = argv[j]; } else { fprintf(stderr, "-o option requires a output filename\n"); exit(1); } } } if (outf && (fo = fopen(outf, "w"))==NULL){ printf("open error!!\n"); exit(1); }
お礼
おかげ様で解決できました。 ご回答ありがとうございました。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
#include <stdio.h> fo = NULL; for(j=1;j<argc-1;j++){ if(strcmp(argv[j],"-o")==0){ if(fo != NULL){ fclose(fo); printf("duplicate -o switch!!\n"); exit(1); } if((fo = fopen(argv[j+1],"w"))==NULL){ printf("open error!!\n"); exit(1); } } } if(fo == NULL){ fo=stdout; } while(fgets(buf,sizeof(buf),fp)!= NULL){ if(strstr(buf,"keyword")!= NULL){ //出力ファイルに出力 fprintf(fo,"%d:%s",line,buf); } } if(fo != stdout){ fclose(fo); } 本来「すべてのコマンドライン引数を評価し終わるまで、fopenなどの実質的な処理を開始しない方が良い」でしょう。 つまり #include <stdio.h> #undef FIRST_SWITCH_ENABLED FILE *fo; char *fo_name; fo = NULL; fo_name = NULL; for(j=1;j<argc-1;j++){ if(strcmp(argv[j],"-o")==0)){ #ifdef FIRST_SWITCH_ENABLED if(fo_name == NULL) //このif文があると「最初の-oが有効」で、if文が無いと「最後の-oが有効」になる #endif fo_name = argv[j+1]; } } if(fo_name != NULL){ if((fo = fopen(fo_name,"w"))==NULL){ printf("open error!!\n"); exit(1); } }else{ fo=stdout; } while(fgets(buf,sizeof(buf),fp)!= NULL){ if(strstr(buf,"keyword")!= NULL){ //出力ファイルに出力 fprintf(fo,"%d:%s",line,buf); } } if((fo_name != NULL)&&(fo != NULL)){ fclose(fo); } とします。 これで、 実行モジュール -o 出力ファイル名1 -b ファイル名 -c ファイル名 -o 出力ファイル名2 -o 出力ファイル名3 と書かれた場合も、引数の解析の途中でエラーで止めずに済みます。 「最初の-o」か「最後の-o」のどちらを有効にするかは、コメントを付けたif文の有無で決まります。 if文の有無は、識別子「FIRST_SWITCH_ENABLED」を定義するか未定義にするかで決まります。
- askaaska
- ベストアンサー率35% (1455/4149)
起動後の処理に コマンドライン引数の内容をチェックする処理を加えればいいのよ。 指定があれば変数fileOutputFlg=trueにして、ファイルを開く。 なければfalseにしておいて。 出力は、例えばwriteLog("",,,)という関数で行い その中で fileOutputFlgがtrueならファイルハンドラ、 falseなら標準出力に出力 こんな感じね。
お礼
なるほど、参考にさせていただきます。 ご回答ありがとうございました。
お礼
なるほど、fopenを後回しにするとできました。 非常に参考になりました。ご回答ありがとうございました。