【C言語】コマンドライン引数の標準入出力
コマンドライン引数で、ファイル名を3つ渡します。-aの次のコマンドライン引数が、出力ファイル名です。
<<例>>
・実行モジュール -a 出力ファイル名 -b ファイル名 -c ファイル名
・実行モジュール -c ファイル名 -a 出力ファイル名 -b ファイル名
もし出力ファイルが指定されなかった場合に、標準入出力を使いたいのですが、どうしたらいいかわかりません。
下記がソースの一部です。これをどう改造したらよいでしょうか。
分かる方いらっしゃいましたらご回答いただけると幸いです。
宜しくお願いします。
//出力ファイルを取得、書き込みモードでオープン
for(j=1;j<argc-1;j++){
if(strcmp(argv[j],"-o")==0){
if((fo = fopen(argv[j+1],"w"))==NULL){
printf("open error!!\n");
exit(1);
}
}
}
while(fgets(buf,sizeof(buf),fp)!= NULL){
if(strstr(buf,"keyword")!= NULL){
//出力ファイルに出力
fprintf(fo,"%d:%s",line,buf);
}
}
No.2
- 回答日時:
#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」を定義するか未定義にするかで決まります。
No.3ベストアンサー
- 回答日時:
追記。
>本来「すべてのコマンドライン引数を評価し終わるまで、fopenなどの実質的な処理を開始しない方が良い」でしょう。
回答の前半に書いた「引数を評価しながらfopenしちゃうプログラム」で
実行モジュール -o 出力ファイル名1 -b ファイル名 -c ファイル名 -o 出力ファイル名2 -o 出力ファイル名3
って実行したら「中身が空の『出力ファイル名1』が作成されてしまってから、duplicate -o switch!ってエラーが表示されて停止してしまう」と思います。
質問者さんも「エラー表示して止まるんだったら、中身が空の『出力ファイル名1』が作成されない方が良い」と思いませんか?
なので「すべてのコマンドライン引数を評価し終わるまで、fopenなどの実質的な処理を開始してはいけない」のです。
No.4
- 回答日時:
> -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);
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Visual Basic(VBA) Excel-VBAでのファイルの開き方 4 2023/02/14 11:01
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- Excel(エクセル) 【VBA】PDF出力に任意のファイル名前を付ける方法 3 2023/07/21 10:55
- その他(データベース) c言語の問題です。これを踏まえてコーディングしたいのでおしえていただきたいです。 3 2023/08/03 09:27
- UNIX・Linux テキストファイルをページ番号付きでコマンドラインから印刷したい 1 2023/02/22 12:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ファイル出力の場所を指定
-
VC++でUTF-8のファイルを出力し...
-
二次元配列をクリップボードに...
-
テキストファイルに改行コード...
-
CreateProcess関数と実行後の戻...
-
C言語での印刷方法
-
構造体のファイル出力
-
ファイルの文字コードをUTF-8に...
-
VB.NETでExcelファイルを出力す...
-
ファイル形式またはファイル拡...
-
プリンタに出力する信号をパソ...
-
Base64でエンコードした後の文...
-
サウンド出力のデバイスを選択...
-
C++ BuilderでPDF出力
-
コマンド(例えばls)の出力結果...
-
Accessでのレポート印刷待機方法
-
setvbufってどう使うの?
-
C言語のローカル変数初期化に...
-
FORTRANの出力データの左寄せが...
-
C言語での出力の上書き方法を教...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コマンド(例えばls)の出力結果...
-
Acccess レポートをグループ別...
-
VC++でUTF-8のファイルを出力し...
-
サウンド出力のデバイスを選択...
-
ファイルの文字コードをUTF-8に...
-
VBA でメモ帳へ保存する際の保...
-
ファイル出力の場所を指定
-
ファイル形式またはファイル拡...
-
テキストファイルに改行コード...
-
シェルコマンドの 2>&1 とはど...
-
Wordマクロで指定したフォルダ...
-
AccessVBA複数レポート条件毎に...
-
二次元配列をクリップボードに...
-
UNIX & Linux の標準出力で得た...
-
フォルダにあるPDF情報の抽出(VBA)
-
C++ BuilderでPDF出力
-
VBSでEXCEL⇒CSV変換で日付の書...
-
fortranのtxtファイル出力書式...
-
CBool関数について VB6とVB.net...
-
ワードからPDF変換でグラフが表...
おすすめ情報