
問題文:文字列を保存する構造体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);
}
}
No.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のアドレスにあるもの」にアクセスしたとき、どうなるかわかりません。
No.4
- 回答日時:
>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
これでなぜ警告になるのかわからないのでしたら、型や変数について勉強し直した方がいいです。
まさかこういう間違いされてるとは思ってなかったんで . と -> のとこかと思ってました(もちろん . と -> の理解も怪しいですが)
No.3
- 回答日時:
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は別物ですので何も入っていません。
# 最初に指摘したとおりどこを指しているのか不定です。
ツッコミどころ満載ですね…本当に……。
No.2
- 回答日時:
とりあえず
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
No.1
- 回答日時:
>という問題で、とりあえず自分で細かい条件は無視して文字列を標準入力してから構造体のメンバに文字を格納するところまでやろうとしたのですが、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
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Word(ワード) 表の縦罫線を移動するピッチ 1 2022/10/12 12:24
- その他(パソコン・周辺機器) WINDOWS11 IMEの日本語入力で困っています 4 2023/04/29 19:24
- Visual Basic(VBA) evcel VBAについて 2 2022/08/02 21:37
- PDF acrobatでwordファイルをpdfに変換すると文字化けする 3 2023/02/10 09:31
- Word(ワード) Word 大学のレポートをWordで書いて提出したんですけど、提出したものを見るとWordファイルの 4 2022/04/17 18:00
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ポインタ配列
-
CStringからchar*への型変換に...
-
文字列str内の全ての数字を...
-
C言語のintとcharの違いってな...
-
char型にint型の数値を代入する。
-
char形配列の整数を抜き出したい
-
char*を初期化したいのですが
-
strcat関数を自作したいです
-
C言語 strstrの実装
-
csvファイルをfscanfで読み込む...
-
strcat関数
-
ポインタの文字の代入について
-
C言語にて構造体のメンバがNULL...
-
エクセルのMID関数は、C言語では?
-
ポインタを使って回文かどうか...
-
構造体・ビットフィールドのvol...
-
C言語のプログラムについてです
-
new charとnew char[N]の違いは?
-
c言語でポインタ変数を用いた配...
-
小数点入りの文字列をfloat型に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringからchar*への型変換に...
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
char型にint型の数値を代入する。
-
C言語にて構造体のメンバがNULL...
-
fgetc( )の戻り値はなぜ整数??
-
char 文字列型 の表現範囲が-12...
-
fstream型オブジェクトを関数の...
-
C++17で、unsigned char * 配列...
-
DWORDとcharの変換
-
文字列内の数字削除
-
new charとnew char[N]の違いは?
-
文字型配列に格納した空白の切捨て
-
C++Builder 2009 テキスト...
-
csvファイルをfscanfで読み込む...
-
文字列の途中から途中までを抽出
-
[C] 構造体メンバーのカンマ区...
-
エクセルのMID関数は、C言語では?
-
小数点入りの文字列をfloat型に...
-
wsprintf( ポインタ , "%d" , "...
おすすめ情報