• ベストアンサー

間接参照のレベルが異なっています

単語を昇順でソートするプログラミングでエラーが出て困っている者です。 エラーが出てる箇所のみ抜粋して、あとは省略したものが下記です。 下記の2つの関数の下の方の関数で 間接参照のレベルが'char **'と'char[10][20]'で異なっています read_wordsの型が2の仮引数および実引数と異なります と言うエラーが現れます。main関数内のsortword関数、display_words関数でも同様にエラーが現れます。 これらの原因は何でしょう。また、僕は何がわかってないですか? ここどこを勉強しろ、等のアドバイスでも結構ですのでぜひご指導ください。お願いします。 #include<stdio.h> #include<stdlib.h> #include<string.h> #define LINE_SIZE 20 #define MAX_LINES 10 char line[MAX_LINES][LINE_SIZE]; int num; int read_words(char *fname,char **line,int num)//用意した構造に文字列を格納 { FILE *fp;//ファイルポインタの宣言 int i = 0;//繰り返し変数の初期化 if((fp = fopen(fname,"r")) == NULL)//ファイルがあるかの確認 { printf("ファイルを開けません\n");//ファイルが無い時はエラーメッセージを出す exit(1);//エラー時は強制終了 } fp=fopen(fname,"r"); fscan(fp,"%d",&line); for(i=0;i<MAX_LINES;i++)//1列ずつ文字列を入れる制御構造 { fscanf(fp,"%s",&line[i]);//ファイルから文字列を変数に入力 i++;//繰り返し変数の増加 } num=line[0];//単語数を戻り値とする fclose(fp);//ファイルのクローズ } int main(int argc,char *argv[]) { read_words(argv[1],line,int num); sortword(line,num); display_words(line,num); }

質問者が選んだベストアンサー

  • ベストアンサー
  • Werner
  • ベストアンサー率53% (395/735)
回答No.3

開発環境が書かれていませんが、書いた方が回答者が回答しやすいと思います。 > int read_words(char *fname,char **line,int num) この関数の第2引数はchar **型なのに、 > char line[MAX_LINES][LINE_SIZE]; > read_words(argv[1],line,int num); 呼び出すときの型が char[MAX_LINES][LINE_SIZE]型になってしまっています。 関数の引数を以下のどれかに変更すればとりあえずそのエラーは出なくなると思います。 int read_words(char *fname,char line[MAX_LINES][LINE_SIZE] ,int num) int read_words(char *fname,char line[][LINE_SIZE] ,int num) int read_words(char *fname,char *line[LINE_SIZE] ,int num) なお、このことに関する詳しいことは下記のページを見てください。 http://www.st.rim.or.jp/~phinloda/cqa/cqa17.html あと気になったところとして、 > char line[MAX_LINES][LINE_SIZE]; グローバル変数にする必要がないので、main関数内で宣言した方がよい。 > fscan(fp,"%d",&line); ・fscanになっている。 ・%dなのに&lineが整数型でない。(&lineはchar *型) ・仮に%sの間違いの場合、 &lineは間違いではないけど、意味的にline[0]にした方が分かりやすそう。 (後ろでline[0]で使ってますし。) > fscanf(fp,"%s",&line[i]);//ファイルから文字列を変数に入力 ・lineがchar **型でもchar[MAX_LINES][LINE_SIZE]型でも &line[i]の型はchar型になる。 ここに要求されるのはchar *型なのでline[i]とするべき。 > num=line[0];//単語数を戻り値とする ・戻り値と書いてあるのにreturnで返していない。(コメントが嘘) ここはグローバル変数numを作らなくてもコメント通りreturnで返せばよいと思いますよ。 そうすればnumをグローバル変数にする必要もなくなります。 ・int型のnumにchar *型のline[0]を代入するのは変。(ポインタが代入されるけどそれでいいの?) > read_words(argv[1],line,int num); ・int numはおかしい(intはいらない)。 > また、僕は何がわかってないですか? あえて言えば、ポインタ・配列が絡んだ"型"がよく分かっていないなという感じがしました。

その他の回答 (5)

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.6

#include<stdio.h> #include<errno.h> #include<stdlib.h> #include<string.h> #define LINE_SIZE 20 #define MAX_LINES 10 void read_words(char *fname, char line[][LINE_SIZE], int *num) { FILE *fp; int i; if ((fp = fopen(fname, "r")) == NULL) { printf("ファイル%sを開けません\n", fname); exit(errno); } for (i = 0; i < MAX_LINES; i++) { if (fgets(line[i], LINE_SIZE, fp) == 0) { break; } line[i][strlen(line[i]) - 1] = 0; } fclose(fp); *num = i; } void display_words(char line[][LINE_SIZE], int num) { int i; for (i = 0; i < num; i++) { printf("%d: %s\n", i + 1, line[i]); } } int strsort(const void *p, const void *q) { return (strcmp(p, q)); } void sortword(char line[][LINE_SIZE], int num) { qsort(line, num, LINE_SIZE, strsort); } int main(int argc, char *argv[]) { char line[MAX_LINES][LINE_SIZE]; int num; read_words(argv[1], line, &num); sortword(line, num); display_words(line, num); return 0; }

回答No.5

もうだいぶはなれてしまったので気の付いた点だけ。 for(i=0;i<MAX_LINES;i++)// でカウントアップしてるのに i++;//繰り返し変数の増加 とは?

  • Werner
  • ベストアンサー率53% (395/735)
回答No.4

すみません。一部不正確なところがありました。 >> fscan(fp,"%d",&line); >・%dなのに&lineが整数型でない。(&lineはchar *型) %dの時は続く引数はint型へのポインタ(int*)である必要があるので間違いです。 (整数型である必要があるというのは間違いです。)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

とりあえず、気の付いた点 char **line で受けた場合、一行の大きさはどのようにしてわかるのでしょうか? この時 line[i] は、何を指していますか >fscan(fp,"%d",&line); は、何を取り込もうとしているのでしょうか?

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.1

char line[MAX_LINES][LINE_SIZE] と char** とが異なる型だからです. int read_words(char *fname,char **line,int num) を int read_words(char *fname,charline[MAX_LINES][LINE_SIZE],int num) に変えればとりあえずエラーはなくなると思いますよ.

関連するQ&A