高校三年生の合唱祭で何を歌いましたか?

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( ) 以外の方法を知りたいです。

A 回答 (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);

}

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

ありがとうございます。
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

_ak1 さんの桁数計算だと、n が 0 の時に 0 桁になってしまうので、


負数にも対応させて、こんな感じ。

int d = 1; // 桁数
int t = n;
if (n < 0) {
i = 2;
t = -n;
}
for (; t >= 10; d++) t /= 10;
    • good
    • 0
この回答へのお礼

kenji_さんの回答も_ak1さんの回答もまだ理解できていないから
inthefloiさんの回答もあまり分からなかったけど
ありがとうございました。

お礼日時:2001/12/21 21:29

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() が必要になります。
    • good
    • 0
この回答へのお礼

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

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 はありえないんで、
関数成否判定のイメージを書いてみました。

ほな、横から失礼しました。
    • good
    • 0
この回答へのお礼

kenji_さんの回答がまだ理解できていないから
_ak1さんの回答もあまり分からなかったけど
ありがとうございました。

お礼日時:2001/12/21 21:27

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演算子を使ったほうが簡単かも?
    • good
    • 0
この回答へのお礼

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

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

sprintf( ) で int を char * に変換する
こともできました。
ありがとうございます。

お礼日時:2001/12/12 21:55

コンパイラにより、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 );
}
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/12/21 21:24

>atoi( ) の反対をやりたい


 ANSI に、itoa(引数注意)があったと思いますが、だめなんでしょうか?
    • good
    • 0
この回答へのお礼

ありがとうございます。
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

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報