c
1char* str { 2 return "文字列を返します。"; 3} 4 5int main(void) { 6 char a[10]; 7 strcpy(a, str()); 8 printf("%s", a); 9}
上のコードは極端な例ですが、ある関数から文字列を返してmain関数内で表示するプログラムを書きたいです。しかし上のコードだとzsh trace trap ./a.outというエラーが出てしまいうまく行きません。
どのように書き直せば良いでしょうか? ちなみに、strに引数を持たせるのは無しで、引数は無しでお願いします。
エラーが出るならメッセージぐらい提示しましょう。
今回はなんとなくわかりますが、
場合によってはまったくわかりません。
エラーメッセージは怒声でも罵声でも罵倒でもハラスメントでもなく、
コンパイラ等からのメッセージです。
つまり、今の状態は『相手の話を聞かずに逆ギレしている人』です。
そんな人はコミュニケーションなんて取れませんよね。
なので、メッセージぐらい読みましょう。
しかも、『関数の書き方』すら満足に書けていません。
内部でmallocすれば出来ますけど極めて"危険"ですよ。
関数の戻り値をstrcpy関数を使用してコピーしようとした意図はなんでしょうか?
教本やWeb等で調べてもそのような戻り値の受け取り方は書いて無いはずですが。
(別にコピーしたっていいんじゃない?)
”上のコードだとzsh trace trap ./a.outというエラーが出てしまい”はエラーメッセージではないのですか?そうだと思って記載してしまいました。
これは即興で作ったコードなので、本来のコードではstrcpyが必要なものもreturnしています。(char*型変数と、文字列のreturnをif文の場合によって分けるコードです。) 例のコードが下手くそですみません。。
> ”上のコードだとzsh trace trap ./a.outというエラーが出てしまい”はエラーメッセージではないのですか?そうだと思って記載してしまいました。
それで特に問題ないです。
fanaさんへ
いや、別にいいんですが、何故そんな変則的なやり方をしようと思ったのか理由が分からなかったので。
char *a = str();
単純に↑でやれば分かりやすいし、何故そうしなかったのかなと。
コード提示する際に要らないところを除去した結果がこの形になっている,ってだけなんじゃないかな.
つまり本物のコードでの関数呼び出し部分がこの形(strcpy)で書かれていて,以降にコピーしたデータをいじくり回すような続きの処理が存在しているのでしょう.
(何故か文法上必要な部分までも除去されてるから,少なくとも本番コードがそのまま示されているわけではないことは想像できる)
コピー処理が問題を起こしているように見えるけども「そもそも何でコピーしたし?」というのは突っ込み方が違うような.
kainaさんへ
strcpyでコピーすることと、char*型変数に代入すること、char型配列に代入することの違いがよくわかっていませんでした。ご指摘ありがとうございました。
初心者は、よくわからないで使っていることが多いです。
そこにstrcpyを使った理由はなんですか?と聞くのは意味のない質問です。『strcpyではなくchar *a = strと書けばうまくいく』というのを後出しではなく最初に言っていただければ、初心者もなぜその書き方ならうまくいくのかを調べることができ、理解を深めることができます。これからもよろしくお願いします。
> そこにstrcpyを使った理由はなんですか?と聞くのは意味のない質問です。
いえ、「なにかの意図を持って書いていたけど、その意図を実現するには別な方法が良かった」のような場合に、その質問から掘り下げることができます(回答者からすれば、「わからずに書いているかどうか」も聞かなければわからないのです)。
問題を起こしている処理がある
→なんかわかんねぇけど,この処理自体を抹消するぜ!
→当然ながら問題が消えた
→ヨシ!
って話でOKなんすか? (いや別に満足ならそれでいいのだが)
う~ん、なんというか勉強の仕方を変えたほうが良いような。
K.M.PEANUTSさんの過去の質問を軽く見てみたのですが、課題で与えられた
問題を解くことが目的になっていて何故そのような書き方をすれば良いかということが
理解出来ないまま進めているように見えます。
課題のプログラムを作成することを目的にしては本末転倒です。
例えば今回の質問であればC言語における関数の呼び出し方、戻り値の受け取り方を
教本で1からきちんと理解出来ていれば自己解決出来た問題かと思います。
fanaさんへ
僕が質問内容は関数から文字列を返す方法だったので、とりあえず質問内容の結果が求められたところで終了しました。『なぜ先程のコードがエラーだったのか』は別の質問になってしまうと思うので、改めてstrcpyやchar型変数の違いを調べて、それでもわからなかったらまた質問させていただこうと思ってます。
質問者さんが自分の質問の意味を理解していないのが問題なんですが・・・
まぁクローズするなら止めませんが。
> 本来のコードではstrcpyが必要なものもreturnしています。(char*型変数と、文字列のreturnをif文の場合によって分けるコードです。)
という話の具体的なところが示されていないので,
ココで言うところの「文字列を返す」ってのは何だろうね? っていう根本があやふやなままに思える.
> char *a = str();
という,なんともヤバそうな雰囲気をまとったコードで本当に大丈夫なのか?っていう.
kainaさんへ
課題を通して自分の理解できていないところを発見し、その都度調べている状況です。ちなみに授業では演習問題が複数題出題され、初めて使う関数なども自分で調べて問題を解かされますし、とくに模範解答も配られず、勝手にやっといてねみたいなスタイルのFランです。 本は新明解を使いました。勉強法を考え直したいと思いますご指摘ありがとうございます。
そもそも、学校の課題は非推奨質問なんですよ。
[推奨していない質問] https://teratail.com/help/avoid-asking
radianさんへ
それは違うと思います。非推奨なのはあくまで"丸投げ"であって、実際にコードを書いてつまずいたところで質問するのはいいはずです。そのためにわざわざコード例を作り(これが下手でしたが)、わからないところを抜粋して質問したのですが、これもだめなのですか?ちなみに提出するものでもありません。学習目的でやっています。
学習目的でやっているということなら、str関数を以下のように書き換えて実行してみるといいでしょう。
char * str()
{
char s[100];
strcpy(s, "文字列を返します。");
return s;
}
つまづくというのは、ネットや本で調べまくってデバッグしても解決しないようなレベルだと思います。この質問はそこまで試行錯誤したようには全く見えません。
neconekocat さん
コード例ありがとうございます!
一応実行結果は正しく動作しましたが、コンパイル時にwarningでaddress of stack memory associated with local variable 's' returnedと表示されました。これは、関数内で定義したchar型配列をreturnしているのがあまり良くないということでしょうか?
それは運悪く、正しく動作しているように見えてるだけです。
関数を抜けた時点で変数はスコープを外れるので値は不定となります。
なんならその領域を再利用される危険もあります。
radianさん
> つまづくというのは、ネットや本で調べまくってデバッグしても解決しないようなレベルだと思います。
あなたの感覚で喋ってますか???
学校が出題してきた問題を質問したから怒ってるのですか?
質問のレベルが低いから怒ってるのですか?
書籍に書いてある問題で質問した場合はいいのですか?
出題元と質問にどのような関係があるのですか?
> スコープを外れるので値は不定となります。
× スコープを外れるので
〇 生存期間がおわるので
別に怒ってはいませんが、もし色々試行錯誤した上での質問であれば、誤解されないような質問文に編集してください。(〇〇という記事を読み、〇〇のサンプルコードを試したが、〇〇という部分が理解できなかった等)
コンパイルすら通らないコードがポンと置いてあるだけだと、丸投げなんだろうなぁと判断せざるを得ないです。
出来れば、下記リンクのページの内容に一通り目を通してください。
[質問するときのヒント] https://teratail.com/help/question-tips
"文字列を返します。" は静的なオブジェクトであり、生存期間はプログラム開始から終了までです。
自動変数と勘違いしているコメントをしている人はもっと勉強してください。
kazuma-sさん
私に対するコメントかな?
質問者が本来のコードではstrcpyが必要なものもreturnしていますと言っているのでそれは無理だよって言ってるだけですけども
生存期間の話は
> neconekocat 2021/07/07 12:19
からの流れで出てきているんだが.
回答5件
あなたの回答
tips
プレビュー