- ベストアンサー
文字列をうまく返してくれない
- 数値を文字列として呼び出し元に渡し、呼び出し元で文字列を数値に変えようとしたのですがatoi関数を使うとうまく行きませんでした。
- どのように変更したらatoiが使える文字列になりますか?
- re_3関数で文字列を生成していますが、ポインタの扱いが間違っているようです。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
str_hは自動変数だから、re_3関数が終了すると同時に消滅するのよね。 消滅させたくないときは、static を付けると良いけど、あまり良い方法じゃないかも。 C++ならポインタじゃなくてオブジェクトにしたいところだけど、C言語だよね? #include <stdio.h> #include <stdlib.h> static struct{ char *name; }kuda[5]={ { "もも" , "りんご" , "みかん" , "バナナ" , "パイナップル" } } char *re_3( void ){ int a = 3; static char str_h[100]; char *str; sprintf_s( str_h , 100 , "%d" , a ); str = str_h; return str; } void main( void ){ printf( "%s" , kuda[ atoi( re_3() ) ].name ); }
その他の回答 (7)
- kawais070
- ベストアンサー率52% (2242/4283)
> 消滅してるからどこにあるかわからないため、 > atoiを使うと0が帰ってくるのですね 不正解。 参照先のメモリーがすでに解放済みの場合の動作は、不定です。 あなたの使っているコンパイラ/実行環境では、たまたま 0 とか 1 を返してくれた、というだけのこと。 コンパイラ/実行環境が変われば、実行結果は変わってきます。 (プログラムミスだから、実行時エラーとかいうことも考えられる) この辺のことを追及する暇があったらさっさとプログラムを直せっちゅうことかな。
お礼
そろそろ今日渡しネットが使える時間が終了時間となりました。 皆様、回答ありがとうございました。 質問を閉めさせていただきます。
補足
プログラムを治すのはいつでもできます。 しかし疑問に思ったことを聞ける時はこの時ぐらいしかありません。 この掲示板もいつまでも使えるわけではないですしね(一日もたてば忘れ去られる可能性高いですし) まあまた改めて質問はできますけどね だからこそ、その時疑問に思ったことを優先すべきだと私は思うのです。 えっとですね 好きな相手ができたら私はすぐ告白して付き合うか云々の話は後付にする方ですよ なぜなら相手は明日事故で死ぬ可能性だってあるのに告白もできずに終わるなんていやですよ 聞いた感じ大多数の人は今日は~だからだめだとか明日の方がいい気がするだとか何やかんやとえらく告白するのをためらうものだねとは思っていますが ですので、私は回答者様との時間との共有や一時的とはいえ師弟の関係を大切にしたいと思っているのです そのため、おそらく私と回答者様は優先順位の違いなのかな? とは思いますね まあ確かに今日ネットが使える時間は後少しなんですけどね <<参照先のメモリーがすでに解放済みの場合の動作は、不定です。 あなたの使っているコンパイラ/実行環境では、たまたま 0 とか 1 を返してくれた、というだけのこと。 こちらの回答はありがとうございました
- Tacosan
- ベストアンサー率23% (3656/15482)
#4 の 1行目の通り. 自動変数のアドレスを返す時点でアウト.
お礼
参照先が消えるからですね
- kawais070
- ベストアンサー率52% (2242/4283)
> すでに使用済みのものなのだから(データーを受け渡し > 完了後ですし)消滅させてもいい気がするのですが。 受け渡しているのは、ポインタですよ。 データは受け渡していません。 ポインタに関しての理解が足りないようですね。 以下のページでも読んで勉強しなおし。 http://www.sgnet.co.jp/c/6-1.html http://www.sgnet.co.jp/c/6-2.html http://www.sgnet.co.jp/c/6-3.html http://www.sgnet.co.jp/c/6-4.html
お礼
読んできました 今まで読んだ中では読みやすいほうではあるのですが、紹介されたぺージと今回の話のつながりがわかりません。
補足
あれ?ということはデーターを受け渡す場合文字を一個づつ渡す方法になりますか? 読んでみます
- Tacosan
- ベストアンサー率23% (3656/15482)
ん~.... 「食わせる数字が "117" だった場合 1が帰ってきたんですよ。」の実例をプログラムで出してもらえませんか? まさか, この質問にあるプログラムで「117 と入力したのに」とかではないですよね.
お礼
わかりました。 実際のプログラムを簡略化したものを作ってきますね 少々お待ちください 後書きませんでしたがDXライブラリを使っています。
補足
簡略化データーを作ってきました 急いで作ったために変なところがあったら申し訳ありません A.cpp の内容 static struct{ char *name[125]; }race={ "モンキーマン", //0に相当する "リザードマン", //1に相当する //117近くも乗せると長いので全て省略 "電子の妖精", //117に相当する }; DrawFormatStringToHandle( 365 , 58 , yellow_s , MG_14_0 , race.name[ strtol( kya_read( 2 , 0 , 0 , 10 , 0 ) ) ] ); //printfと同じもので位置、色、書式、何を書きたいかを指定している B.cpp の内容 static struct{ char *name; //キャラ名 double d_data[20]; //double数値 int i_data[16]; //int数値 double s_data[18]; //文字列 }kya_data[2]={ { "雛" , { 43.0000 , //HP 54.0000 , //MP } , { 50 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , //空腹・渇き・ストレス・疲労・排尿・排糞・スタミナ・性欲・睡眠 5 , 117 , 27 , -1 , 0 , 330 , 10 , 3000 , //種族・クラス・役職・識別・性別・年・上限・金 } , { 0.100,//適性とか 0.100, 0.100, 0.100, } , { { 0 , 0 , 0 } , { 0 , 0 , 0 } , } },{ "泉" , {108.0000 , 20.0000 , } , { 50 , 50 , 50 , 50 , 50 , 50 , 50 , 1 , 1 , 1 , -1 , 1 , 330 , 1 , 5000 , }, { 0.100, 0.100, 0.100, 0.100, }, { { 0 , 0 , 0 } , { 0 , 0 , 0 } , } } }; char *kya_read( int mode1 , int mode2 , int num , int num2 , int num3 ){ //呼び出し //mode2 は計算用 char *read_d , read_h[128]; switch( mode1 ){ case 0: read_d = kya_data[ num ].name; break; case 1: sprintf_s( read_h , 100 , "%d" , (int)kya_data[ num ].d_data[ num2 ] ); read_d = (char *)read_h; break; case 2: sprintf_s( read_h , 100 , "%d" , kya_data[ num ].i_data[ num2 ] ); read_d = (char *)read_h; break; case 3: sprintf_s( read_h , 100 , "%d" , (int)kya_data[ num ].s_data[ num2 ] ); read_d = (char *)read_h; break; case 4: sprintf_s( read_h , 100 , "%d" , kya_data[ num ].state[ num2 ][ num3 ] ); read_d = (char *)read_h; break; } return read_d; } //私が表示したいのは電子の妖精なのにatoi使うとモンキーマンが //strtol使うとリザードマンになる
- asuncion
- ベストアンサー率33% (2127/6289)
ところで、 >strtolを使うと最初の文字のみ帰ってくるため2桁以上の数値に対応できない そんなはずはありません。 まあ、strtol()に食わせる文字列が"1abc"だったりすると 当然結果は数値の1となりますが…。
お礼
食わせる数字が "117" だった場合 1が帰ってきたんですよ。 117が帰ってきた場合は質問せずそのまま使ってましたけどね。 あ、それとすみません 特定環境の関数を使っていて変なところで気を使わせて申し訳ありません
- asuncion
- ベストアンサー率33% (2127/6289)
私はMicrosoftの開発環境を使っていません。 以下のコードを適当に改変してください。 #include <stdio.h> struct { char *name; } kuda[5] = { "もも", "りんご", "みかん", "バナナ", "パイナップル" }; char *re_3(void) { int a = 3; char str_h[100]; char *str; sprintf(str_h, "%d", a); str = str_h; return str; } int main(void) { printf("%s\n", kuda[atoi(re_3())].name); return 0; }
お礼
すみません atoi 使用後 数値が0になってしまいます。
- Ogre7077
- ベストアンサー率65% (170/258)
char* re_3(char* str_h) { int a = 3; sprintf_s( str_h , 100 , "%d" , a ); return str_h; } void main( void ){ char str_h[100]; printf( "%s" , kuda[ atoi( re_3(str_h) ) ].name ); }
お礼
すみません 呼び出し元で変数を使うわけにはいかないので、可能なのかもしれませんができません。他の方法はございませんか?
お礼
おおおできました でも何故? すでに使用済みのものなのだから(データーを受け渡し完了後ですし)消滅させてもいい気がするのですが。 はいC++ではなくC言語です
補足
NO5の修正 2人目のデーターの 50 , 50 , 50 , 50 , 50 , 50 , 50 , なのですが省略し過ぎました 正しくは 50 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , でした NO6補足 atoi を使う時に何故データーが消えるのかがわかりました参照先(アドレス)が消滅してるからどこにあるかわからないため、atoiを使うと0が帰ってくるのですね ですが、もしそうだと疑問が出てくるのですが、 ・strtolを使うと何故1が帰ってくる? ・atoiを使用する前は何故文字列データーとしては扱える? と逆に疑問が出てきます。