アプリ版:「スタンプのみでお礼する」機能のリリースについて

単語を昇順でソートするプログラミングでエラーが出て困っている者です。
エラーが出てる箇所のみ抜粋して、あとは省略したものが下記です。
下記の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);
}

A 回答 (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;
}
    • good
    • 0

もうだいぶはなれてしまったので気の付いた点だけ。


for(i=0;i<MAX_LINES;i++)//
でカウントアップしてるのに
i++;//繰り返し変数の増加
とは?
    • good
    • 0

すみません。

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

開発環境が書かれていませんが、書いた方が回答者が回答しやすいと思います。



> 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はいらない)。


> また、僕は何がわかってないですか?
あえて言えば、ポインタ・配列が絡んだ"型"がよく分かっていないなという感じがしました。
    • good
    • 0

とりあえず、気の付いた点


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

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)
に変えればとりあえずエラーはなくなると思いますよ.
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A