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

問題文:文字列を保存する構造体word_pairを下記の様に定義する。
typedef struct word_pair{
char longer_word[10];
char shorter_word[10];
char combined_word[20];
int longer_word_length;
int shorter_word_length;
}word_pair_t;
この構造体を新たに作成し、データをセットして返す関数
word_pair_t create_word_pair(char *a, char *b);
を作成せよ。create_word_pairは以下の仕様を満たす。
create_word_pairは2つの文字列a,bを比較し、長い文字列をlonger_wordに、短い文字列をshorter_wordに代入する。また、これらの長さが同じ場合には辞書的に後ろのものをlonger_wordに、前のものをshorter_wordに代入する。もし、a,bがまったく同じ文字列であれば、エラーメッセージを出力した上で、longer_wordに入力された文字列をshorter_wordに空の文字列を代入する。またcombined_wordにはlonger_word とshorter_wordをスペース区切りで結合したものを代入する。
標準入力から文字列を2つ読み取り、create_word_pairを用いて、新たにそれらのデータが代入された構造体を作成した後に、これらのメンバ変数を全て、標準出力に表示するプログラムを作成せよ。

という問題で、とりあえず自分で細かい条件は無視して文字列を標準入力してから構造体のメンバに文字を格納するところまでやろうとしたのですが、strcpyするのに型が違うとコンパイルエラーが出たのですが、型は一緒だと私は思っているため、なぜ違うのかわかりません。
また辞書的に後ろ前をif文でどのように表現すればいいのかと、文字列結合にstrcatを使うと思うのですが、結合の合間にスペースをいれる方法が分かりません。以下自分のコード。
#include<stdio.h>
#include<string.h>

#define max 50


typedef struct word_pair{
char longer_word[10];
char shorter_word[10];
char combined_word[20];
int longer_word_length;
int shorter_word_length;
}word_pair_t;

word_pair_t create_word_pair(char *a, char *b);


int main()
{

char a[max],b[max];
word_pair_t *str;



printf("文字列を2つ入力してください。\n");
printf("1つ目:");
scanf("%s\n",a);
printf("2つ目:");
scanf("%s\n",b);
create_word_pair(a,b);

printf("長い方の文字列%s\n",str->longer_word);
printf("短い方の文字列%s\n",str->shorter_word);
printf("連結した文字列%s\n",str->combined_word);
printf("長い方の文字列の長さ%d\n",str->longer_word_length);
printf("短い方の文字列の長さ%d\n",str->shorter_word_length);

return 0;

}


word_pair_t create_word_pair(char *a, char *b)
{





int d, e;
char c[max];
word_pair_t *str;
d = strlen(a);
e = strlen(b);
if(d > e){

strcpy(str->longer_word, a);
strcpy(str->shorter_word, b);
c = strcat(a,b);
strcpy(str->combine_word, c);
strcpy(str->longer_word_length, d);
strcpy(str->shorter_word_length, e);


}
if(d < e)
{

strcpy(str.longer_word, b);
strcpy(str.shorter_word, a);
c = strcat(a,b);
strcpy(str.combine_word, c);

strcpy(str.longer_word_length, e);
strcpy(str.shorter_word_length, d);




}


}

A 回答 (5件)

intを返す関数を考えたときに



int func(){
int a;

return a;
}

int main(){
int a ;

a = func() ;

}
みたいになりますよね?
このとき、funcのaとmainのaはともに関数内だけのローカル変数になっていて、互いに関係無い、っていうのも大丈夫ですね。
名前が同じでややこしければ
int func(){
int func_a;

return func_a;
}

int main(){
int main_a ;

main_a = func() ;

}
と考えれば、とりあえずはよいでしょう。
/* ここがわからなければ、とりあえず、過去の学習内容を復習してください */

構造体は、intなどとほぼ同じ「型」です。ですから、int→構造体に書き換えたものが「構造体を返す関数」の基本になります。
struct A func(){
struct A a;

return a;
}

int main(){
struct A a ;

a = func() ;

}

ごく古いC言語の仕様だと、構造体を直接返したり、=で代入したりができませんでしたが、今は可能です。
/* メンバーにポインタが入っていると、注意する必要があります。
興味があったら ナローコピー/ディープコピーで検索。
今回の例では問題ありません */


> 最初に構造体宣言をしているからポインタで構造体の中の数値は変えることができるんじゃないんですか?

「構造体」は宣言されています。
しかし、その「構造体の変数」は宣言されていません。
これは「int」はどこでも使えるけど、「int型の変数」は宣言した範囲でしか使えない、というのと同じです。

また、ポインタでの操作、というのは、なんらかの形(通常は引数)でポインタを関数に渡すことで、そのポインタを通じて呼び出し側の構造体を操作するものです。
void func(struct A * a ){

a->b = 0 ; /* a->b は (*a).b の意味 */

}

int main(){
struct A c ;

func(&c) ;
/* c.b == 0 */

}

このような時に
・mainのcのアドレスが引数aとしてfuncに渡される
・ -> 演算子で、ポインタaが指すアドレスにある構造体Aのメンバーbを操作
= aはmain関数内の変数cを指しているので、cのメンバーbが変化する
となります。
これも、他の型を同じです。

このプログラムだと、word_pair_t *str;と宣言しているだけで、何もアドレスを入れていません。
C言語では、このような場合に、何が入っているか保証されていません。
このままstr-> 等として「strのアドレスにあるもの」にアクセスしたとき、どうなるかわかりません。
    • good
    • 0

>hkadai4-3.c:75: 警告: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast


>hkadai4-3.c:75: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast

この警告は

>strcpy(str->longer_word_length, d);

に対する警告だと思いますが(元のソースの行番号がわからないから推測)、これが警告になる理由がわからないということでしょうか。

strcpyのプロトタイプはだいたいこんな感じ
char *strcpy(char *, const char *);

対して
longer_word_lengthとdの型はint

これでなぜ警告になるのかわからないのでしたら、型や変数について勉強し直した方がいいです。

まさかこういう間違いされてるとは思ってなかったんで . と -> のとこかと思ってました(もちろん . と -> の理解も怪しいですが)
    • good
    • 0

create_word_pair()で使っている


word_pair_t *str;
のポインタはいったいドコ指しているんでしょうか?
mainのword_pair_t *str;もドコを指しているんでしょう?

>c = strcat(a,b);

配列に代入できません。
strcpy(c, a);
strcat(c, b);
なんじゃないですか?
あふれかえってメモリ破壊するかも知れませんけど。
50バイト+50バイトは50バイトでしょうか?
そして、50バイト(100バイト?)のデータをcombine_word(combined_word?)の20バイトにどうやって押し込みましょうか?

>文字列結合にstrcatを使うと思うのですが、結合の合間にスペースをいれる方法が分かりません。

strcpy(c, a);
strcat(c, " ");
strcat(c, b);
ですか?
sprintf(c, "%s %s", a, b);
なんてのもありでしょうか?
# やっぱり溢れかえる可能性はあるワケですが。

>strcpy(str->longer_word_length, d);
>strcpy(str->shorter_word_length, e);

int型のコピーにstrcpy()は使いません(使えません)。

create_word_pair()は何も返していません。
returnで指定された型の戻り値を返す必要がありますが…。

で、returnで返しても…
>create_word_pair(a,b);
捨てています。

>printf("長い方の文字列%s\n",str->longer_word);
>  :
>printf("短い方の文字列の長さ%d\n",str->shorter_word_length);

create_word_pair()kstrとmain()のstrは別物ですので何も入っていません。
# 最初に指摘したとおりどこを指しているのか不定です。


ツッコミどころ満載ですね…本当に……。
    • good
    • 0

とりあえず


mainのword_pair_t *str;と
create_word_pairのword_pair_t *str;とは別ものだって理解してます?

create_word_pairが値返してない、とかでませんか?

create_word_pairが返した値、受け取ってません。


構造体が戻り値になっていても、基本の作り方は、int等と同じです。

この回答への補足

コンパイルエラーの内容です。関数内で使う変数は関数内でしか参照できないって事が違いですか?最初に構造体宣言をしているからポインタで構造体の中の数値は変えることができるんじゃないんですか?あと戻り値についてですがどういう風に書けばいいんでしょうか?

hkadai4-3.c: In function ‘create_word_pair’:
hkadai4-3.c:73: error: incompatible types in assignment
hkadai4-3.c:74: error: ‘word_pair_t’ has no member named ‘combine_word’
hkadai4-3.c:75: 警告: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:75: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:76: 警告: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:76: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:83: error: request for member ‘longer_word’ in something not a structure or union
hkadai4-3.c:84: error: request for member ‘shorter_word’ in something not a structure or union
hkadai4-3.c:85: error: incompatible types in assignment
hkadai4-3.c:86: error: request for member ‘combine_word’ in something not a structure or union
hkadai4-3.c:88: error: request for member ‘longer_word_length’ in something not a structure or union
hkadai4-3.c:88: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:89: error: request for member ‘shorter_word_length’ in something not a structure or union
hkadai4-3.c:89: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast

補足日時:2012/08/21 22:29
    • good
    • 0

>という問題で、とりあえず自分で細かい条件は無視して文字列を標準入力してから構造体のメンバに文字を格納するところまでやろうとしたのですが、strcpyするのに型が違うとコンパイルエラーが出たのですが、型は一緒だと私は思っているため、なぜ違うのかわかりません。



本当にエラーメッセージはそのような内容でしたか?
. と -> はどう違うのか理解してますか?

他にも突っ込みどころ満載だけど・・・

この回答への補足

コンパイルエラー内容です
hkadai4-3.c: In function ‘create_word_pair’:
hkadai4-3.c:73: error: incompatible types in assignment
hkadai4-3.c:74: error: ‘word_pair_t’ has no member named ‘combine_word’
hkadai4-3.c:75: 警告: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:75: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:76: 警告: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:76: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:83: error: request for member ‘longer_word’ in something not a structure or union
hkadai4-3.c:84: error: request for member ‘shorter_word’ in something not a structure or union
hkadai4-3.c:85: error: incompatible types in assignment
hkadai4-3.c:86: error: request for member ‘combine_word’ in something not a structure or union
hkadai4-3.c:88: error: request for member ‘longer_word_length’ in something not a structure or union
hkadai4-3.c:88: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast
hkadai4-3.c:89: error: request for member ‘shorter_word_length’ in something not a structure or union
hkadai4-3.c:89: 警告: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast

補足日時:2012/08/21 22:30
    • good
    • 0

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