- ベストアンサー
atoi( ) の反対をやりたい
int型 を charの配列型 にしたいんだけど、 そういう関数がなさそうだから、そういう動作を するものを作ってみました。 #include <iostream.h> main(){ int n = 123; char c[4]; for (int i=4-2; i>=0; i--) { c[i] = n%10+48; n/=10; } c[4-1] = '\0'; cout << c; } char c[4]; の部分が気に入りません。 4 という数字を int n = 123; の桁数の 3+1 で やりたいんだけど、配列の添え字は定数でないと いけないらしく、それはできませんでした。 malloc( ) というものを使ったことがないんだけど 配列の宣言後に malloc() とかで配列のメモリを 変える方法があったら教えてください。 全体的に、int型 を charの配列型 にする考え方で もっとよい方法とか、それをする関数があれば 教えてください。 vecter( ) を使った場合では、出力する時に、 cout << hairetu[0]; cout << hairetu[1]; cout << hairetu[2]; というふうにしないとだめみたいで、普通の配列と違って cout << hairetu; で出力できなかったから vecter( ) 以外の方法を知りたいです。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 sprintf()を使用すると言う点ではNo.3の方の回答で良いと思いますが、 c = (char *)malloc(strlen(n)); malloc()の引数であるstrlen(n)の部分はまずいですね。 (No.3の方申し訳ありません。。。。) strlen()の引数はchar *であるため上記の例では意図しないアドレスを参照してしまいます。 当方の環境ではコアダンプしました。当然のことですが。 ご質問から、変換後のバイト数をきっちりと確保されたいようですが、これは一発では難しいと思います。 仮にそうされるのであれば、以下の様にすれば可能だと思います。(No.3の方のソースを流用させて頂きます) #include <stdio.h> #include <stdlib.h> #include <string.h> main() { int n = 123; char *c; char *tmp; tmp = (char *)malloc(20); ←適当にメモリを確保する sprintf(tmp,"%d",n); c = (char *)malloc(strlen(tmp)+1); strcpy(c, tmp); printf ("変換後=%s\n", c); } と言った感じでしょうか。何だか意味なさげなプログラムになってしまいましたが。すみません。やはり、桁数は地道に計算で出すしかないのかな?っと思っております。
その他の回答 (6)
_ak1 さんの桁数計算だと、n が 0 の時に 0 桁になってしまうので、 負数にも対応させて、こんな感じ。 int d = 1; // 桁数 int t = n; if (n < 0) { i = 2; t = -n; } for (; t >= 10; d++) t /= 10;
お礼
kenji_さんの回答も_ak1さんの回答もまだ理解できていないから inthefloiさんの回答もあまり分からなかったけど ありがとうございました。
- a-kuma
- ベストアンサー率50% (1122/2211)
c++ の方が簡単ですよ。 c++ には、文字列を扱う stream があります。まずは、実例を。 #include <strstream.h> #include <iostream.h> int main() { strstream s; int i = 12345; s << i; cout << s.str() << endl; return 0; } strstream は、内部バッファ(メモリ)に情報を貯える stream です。 貯えた情報を指す char のポインタを取得するには str() メソッドを使います。 これは、strstream が抱えている領域を指しているだけですから、strstream の インスタンスが無くなると不当な領域を指してしまいます。変換した結果を 別途、保存しておきたいのであれば、以下のような感じになります。 char* data; data = new char[ strlen(s.str()) + 1 ]; strcpy(data, s.str()); もしくは、 char* data; data = strdup(s.str()); 両方とも、領域を割当てていますから、別途 delete や free() が必要になります。
お礼
int を char * に変換する方法で、 sprintf( ) 以外にも便利なものがあったんですねー。 int main( ){ strstream s; int n; cout << "数字入力"; // 123 cin >> n; s << n; cout << s.str( ) << '\n'; char *doruzero = ""; strcat(s.str( ), doruzero); // s.str( ) がchar型ならエラーにならんはず } 結果は 数字入力123 123 できました。 コンパイル後にメモリ確保も、malloc( ) 以外に new が使えるのは知りませんでした。 ここで教えてもらって、初めて new というものを 使ってみました。 main( ){ int n; cout << "数字の桁数入力"; // 3 cin >> n; char *c; c = new char[n+1]; printf("%#x\n", *(c+3)); cout << sizeof(c); } 結果は 数字の桁数入力3 0x0 4 できました。 delete や free( ) での解放については 後で調べてみます。 ありがとうございました。
- NUNUNUNUNU
- ベストアンサー率55% (11/20)
kenji_さんの回答に少し補足を。 > c = (char *)malloc(strlen(n)); strlen(n) だとちょっとおかしいようで。 int i; for( i = 0; n; i++ ) n /= 10; c = (char*)malloc( i + 1 ); // c = new char[ i + 1 ]; > sprintf(c,"%d",n); > printf ("変換後=%s\n", c); ついでにこれも欲しいです。 free( c ); // delete[] c; hwangさんの回答にも少し補足を。 > char wk[21]; /* work area */ > > sprintf (wk, "%d", i_data); > if (strlen (wk) > 16 ) { /* 通常は16桁で十分変換エラー */ > return (-1); sprintfが失敗した場合, 不定なwkに対してstrlenをしてしまうことになり具合が 良くないようです。(下手すると例外) int len = sprintf (wk, "%d", i_data); if (len > 16 || len < 1) { /* 通常は16桁で十分変換エラー */ といった感じで、失敗を見る場合、戻り値で見た方がよさそうですね。 ゆーても sprintf の成否って普段見ないんでちょっと迷いました。 今回は多分以降の memcpy に備えてだとは思うんですが、sprintf での失敗でしか strlen(wk) > 16 はありえないんで、 関数成否判定のイメージを書いてみました。 ほな、横から失礼しました。
お礼
kenji_さんの回答がまだ理解できていないから _ak1さんの回答もあまり分からなかったけど ありがとうございました。
- kenji_
- ベストアンサー率0% (0/1)
sprintf()を使えばint型からchar型に変換可能です。 上プログラムをこれで書き換えると #include <stdio.h> #include <stdlib.h> #include <string.h> main() { int n = 123; char *c; c = (char *)malloc(strlen(n)); sprintf(c,"%d",n); printf ("変換後=%s\n", c); } こんな感じになります。 C++のようなのでmallocでなく new演算子を使ったほうが簡単かも?
お礼
char *c; c = (char *)malloc(4); sprintf(c,"%d",n); でできました。 malloc( ) の使い方が分かりました。 malloc( ) の引数の 4 は、while(n/10) を 使って得ることができました。 sprintf( ) で int を char * に変換する こともできました。 ありがとうございます。
- hwang
- ベストアンサー率0% (0/1)
コンパイラにより、itoaがないかもしれない 下記の方法は出来ます。 #include <stdio.h> #include <stdlib.h> #include <string.h> int Int_To_Char (int, char *); int main( argc,argv ) int argc; char *argv[]; { int ret = 0; char c[20]; int i = 123; memset (c, NULL, sizeof (c)); /* 初期値の初期化 */ ret = Int_To_Char (i, c); printf ("変換後 = [%s]\n", c); } /* * Int_To_Char ():文字列型変換(Int型→文字列) * */ int Int_To_Char ( i_data, o_buf ) int i_data; /* 変換元データ */ char *o_buf; /* 変換先文字列 */ { char wk[21]; /* work area */ sprintf (wk, "%d", i_data); if (strlen (wk) > 16 ) { /* 通常は16桁で十分変換エラー */ return (-1); } memcpy (o_buf, wk, strlen(wk)); return ( 0 ); }
お礼
memset( ) も memcpy( ) も知らなかったから まだ理解できていないけど、こんなふうに 説明よりもソースメインに書いてくれる解答は 大好きです。 ありがとうございます。
- ykkw_2001
- ベストアンサー率26% (267/1014)
>atoi( ) の反対をやりたい ANSI に、itoa(引数注意)があったと思いますが、だめなんでしょうか?
お礼
ありがとうございます。 itoa( ) は知りませんでした。 itoa( ) は bcc32 で使えて、考え中です。 itoa( ) を使わない方法も考えたいです。 #include <iostream.h> main( ){ int n; cout << "数字入力"; // 123 cin << n; char c[4]; itoa(c,n,10); // 123を10進として解釈し、char型の配列にする char *doruzero = ""; strcat(c, doruzero); // c が本当にchar型ならエラーにならんはず printf("%x",c); cout << '\n' << c; getchar( ); } エラー E2094 test.cpp 5: << 演算子が使われたがクラス istream では int 型のための定義が存在しない(関数 main( ) ) エラー E2285 test.cpp 7: 'itoa(char *,int,int)' に 一致するものが見つからない(関数 main( ) ) *** 2 errors in Compile ***
お礼
ありがとうございます。 No.3 の kenji_ さんの c = (char *)malloc(strlen(n)); は間違っているは、見てすぐにわかったけど、 それを見て、123 の桁数を使うという意味は伝わりました。 でも、 c = (char *)malloc(strlen(n+1)); でないとおかしいかなと思っていたら、 pikacchuさんは strlen(tmp)+1 としていたから、やっぱり、123 の3桁に1を足した4が malloc( ) の引数ですよね。