OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

atoi( ) の反対をやりたい

  • 暇なときにでも
  • 質問No.183569
  • 閲覧数1508
  • ありがとう数8
  • 気になる数0
  • 回答数7
  • コメント数0

お礼率 59% (194/328)

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
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.4
レベル7

ベストアンサー率 44% (11/25)

こんにちは。
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);

}

と言った感じでしょうか。何だか意味なさげなプログラムになってしまいましたが。すみません。やはり、桁数は地道に計算で出すしかないのかな?っと思っております。
お礼コメント
A__

お礼率 59% (194/328)

ありがとうございます。
No.3 の kenji_ さんの
c = (char *)malloc(strlen(n));
は間違っているは、見てすぐにわかったけど、
それを見て、123 の桁数を使うという意味は伝わりました。
でも、
c = (char *)malloc(strlen(n+1));
でないとおかしいかなと思っていたら、
pikacchuさんは
strlen(tmp)+1
としていたから、やっぱり、123 の3桁に1を足した4が
malloc( ) の引数ですよね。
投稿日時 - 2001-12-12 22:01:02
-PR-
-PR-

その他の回答 (全6件)

  • 回答No.2
レベル6

ベストアンサー率 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[]; ...続きを読む
コンパイラにより、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;/* 変換先文字列*/
{
charwk[21];/* work area*/

sprintf (wk, "%d", i_data);
if (strlen (wk) > 16 ) { /* 通常は16桁で十分変換エラー */
return (-1);
}
memcpy (o_buf, wk, strlen(wk));

return ( 0 );
}
お礼コメント
A__

お礼率 59% (194/328)

memset( ) も memcpy( ) も知らなかったから
まだ理解できていないけど、こんなふうに
説明よりもソースメインに書いてくれる解答は
大好きです。
ありがとうございます。
投稿日時 - 2001-12-21 21:24:33


  • 回答No.1
レベル13

ベストアンサー率 26% (267/1014)

>atoi( ) の反対をやりたい  ANSI に、itoa(引数注意)があったと思いますが、だめなんでしょうか? ...続きを読む
>atoi( ) の反対をやりたい
 ANSI に、itoa(引数注意)があったと思いますが、だめなんでしょうか?
お礼コメント
A__

お礼率 59% (194/328)

ありがとうございます。
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 ***
投稿日時 - 2001-12-12 12:57:51
  • 回答No.3
レベル2

ベストアンサー率 0% (0/1)

sprintf()を使えばint型からchar型に変換可能です。 上プログラムをこれで書き換えると #include <stdio.h> #include <stdlib.h> #include <string.h> main() { int n = 123; char *c; c = (char *)m ...続きを読む
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演算子を使ったほうが簡単かも?
お礼コメント
A__

お礼率 59% (194/328)

char *c;
c = (char *)malloc(4);
sprintf(c,"%d",n);

でできました。
malloc( ) の使い方が分かりました。
malloc( ) の引数の 4 は、while(n/10) を
使って得ることができました。

sprintf( ) で int を char * に変換する
こともできました。
ありがとうございます。
投稿日時 - 2001-12-12 21:55:23
  • 回答No.5
レベル8

ベストアンサー率 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 ...続きを読む
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 はありえないんで、
関数成否判定のイメージを書いてみました。

ほな、横から失礼しました。
お礼コメント
A__

お礼率 59% (194/328)

kenji_さんの回答がまだ理解できていないから
_ak1さんの回答もあまり分からなかったけど
ありがとうございました。
投稿日時 - 2001-12-21 21:27:43
  • 回答No.6
レベル14

ベストアンサー率 50% (1122/2211)

c++ の方が簡単ですよ。 c++ には、文字列を扱う stream があります。まずは、実例を。 #include <strstream.h> #include <iostream.h> int main() {   strstream s;   int i = 12345;   s << i;   cout << s.str() ...続きを読む
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() が必要になります。
お礼コメント
A__

お礼率 59% (194/328)

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( ) での解放については
後で調べてみます。
ありがとうございました。
投稿日時 - 2001-12-12 23:26:35
  • 回答No.7

_ak1 さんの桁数計算だと、n が 0 の時に 0 桁になってしまうので、 負数にも対応させて、こんな感じ。 int d = 1; // 桁数 int t = n; if (n < 0) { i = 2; t = -n; } for (; t >= 10; d++) t /= 10; ...続きを読む
_ak1 さんの桁数計算だと、n が 0 の時に 0 桁になってしまうので、
負数にも対応させて、こんな感じ。

int d = 1; // 桁数
int t = n;
if (n < 0) {
i = 2;
t = -n;
}
for (; t >= 10; d++) t /= 10;
お礼コメント
A__

お礼率 59% (194/328)

kenji_さんの回答も_ak1さんの回答もまだ理解できていないから
inthefloiさんの回答もあまり分からなかったけど
ありがとうございました。
投稿日時 - 2001-12-21 21:29:09
このQ&Aのテーマ
このQ&Aで解決しましたか?
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ