ページ 11

ファイルの入出力について

Posted: 2013年10月06日(日) 16:10
by ライム
ファイルから指定された単語を見つけ、ファイル名:行数:その行を表示するプログラムを作りたいです。第一引数として検索単語、第二引数からはファイル名とします。使うのはC言語です。
一応下記のプログラムでコンパイルはエラーなしにできるのですが、実行すると何もコマンドに出力されません。
どこが間違っているのかご指摘よろしくお願いします。

コード:

#include <stdio.h>
#include<string.h>
int main(int argc, char *argv[]){
  FILE *fp;
  int i;
  char a[256];
  if(argc<3){
	printf("cerror");exit(1);
	}
  char *tmp = argv[1];

  for(i=2;i<argc;i++){
	char *filename = argv[i];
	int Line=1;
	fp=fopen(filename,"r");
	if(NULL==fp){printf("Can not open %s\n",filename);exit(1);}
	while((i=fscanf(fp,"%d", &a[256]))!=EOF){
	break;
	int k=0;
		if((strcmp(a,tmp))==0){k++;
		     printf("%s : %d行目 : %d個目の%sを発見 : %s\n",filename,Line,k,tmp,a);
		}
	}
	Line++;
  }
  fclose(fp);
}

Re: ファイルの入出力について

Posted: 2013年10月06日(日) 16:50
by box
ライム さんが書きました:どこが間違っているのかご指摘よろしくお願いします。
決定的に正しくないと思われるのはここです。
ライム さんが書きました:

コード:

	while((i=fscanf(fp,"%d", &a[256]))!=EOF){
a[256] という、配列の定義範囲外の領域に書き込もうとしています。
fscanf() の書式制御文字列が "%d" である理由がわかりません。
fscanf() の戻り値で、ループ制御変数 i を書き換えるのは正しいでしょうか。

Re: ファイルの入出力について

Posted: 2013年10月06日(日) 17:12
by みけCAT
while文の中身の最初でbreakしているので、「正しい」使い方をすれば何も表示されないのは当たり前です。
多分、与える引数を1個以下にするか、存在しないファイル名を与えれば、何か表示されるかもしれません。
この時、標準出力のリダイレクトをしないのがコツです。
オフトピック
俺が指摘しても、また無視されちゃうかもな・・・
機械的に「ありがとうございました」とだけ言われてもな・・・

Re: ファイルの入出力について

Posted: 2013年10月06日(日) 17:34
by ライム
boxさん、みけCATさん、ご指摘ありがとうございます。
みけCATさん、前回のトピックスで気分を害してしまって申し訳ありません。
私はプログラミング初心者で本当に知識不足で、ご指摘いただいてもすぐにどこがおかしくてどうしたらいいのかがわかりませんでした。
前回おっしゃっていただいたところが、まだ直ってませんでした。
boxさんのご指摘も、前回みけCATさんにご指摘いただいたところでした。
そこも含め自分なりに直してみました。
breakは勘違いでつけてしまっていたようです。
iも上のfor文の変数とごっちゃになってました。
お恥ずかしい限りです。
下記のプログラムで無事実行することができました。
私の未熟さゆえ、回答してくださる方々に不快な思いをさせてしまうことがあるとは思うのですが、精進したいと思いますので、今後ともぜひよろしくお願いします。

コード:


#include <stdio.h>
#include<string.h>
int main(int argc, char *argv[]){
  FILE *fp;
  int i,n;
  char a[256];
  if(argc<3){
	printf("cerror");exit(1);
	}
  char *tmp = argv[1];

  for(i=2;i<argc;i++){
	char *filename = argv[i];
	int Line=1;
	fp=fopen(filename,"r");
	if(NULL==fp){printf("Can not open %s\n",filename);exit(1);}
	while((n=fscanf(fp,"%s", a))!=EOF){
	break;
	int k=0;
		if((strcmp(a,tmp))==0){k++;
		     printf("%s : %d行目 : %d個目の%sを発見 : %s\n",filename,Line,k,tmp,a);
		}
	}
	Line++;
  }
  fclose(fp);
}

Re: ファイルの入出力について

Posted: 2013年10月06日(日) 17:53
by みけCAT
本当にこの仕様でいいのですか?
・break文が消えていません。(言ったそばからまた無視?)
・printfに渡されるLine、kの値はどちらも1固定です。(そもそもbreakがあるのでprintfは呼び出されませんが)

以下は実行には影響ありません。
・fscanfの戻り値を代入したnが、ほかの場所で使われていないようです。
・検索文字列を入れる変数名「tmp」はわかりにくいです。
・このコードで言うtmpとfilenameはconst charの方がいいかもしれません。
・正常終了したときは、main関数は0を返すべきです。