• ベストアンサー

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

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

  • ベストアンサー
  • pikacchu
  • ベストアンサー率44% (11/25)
回答No.4

こんにちは。 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__
質問者

お礼

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

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (6)

noname#30727
noname#30727
回答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;

A__
質問者

お礼

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

全文を見る
すると、全ての回答が全文表示されます。
  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.6

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__
質問者

お礼

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( ) での解放については 後で調べてみます。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
回答No.5

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__
質問者

お礼

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

全文を見る
すると、全ての回答が全文表示されます。
  • kenji_
  • ベストアンサー率0% (0/1)
回答No.3

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__
質問者

お礼

char *c; c = (char *)malloc(4); sprintf(c,"%d",n); でできました。 malloc( ) の使い方が分かりました。 malloc( ) の引数の 4 は、while(n/10) を 使って得ることができました。 sprintf( ) で int を char * に変換する こともできました。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • hwang
  • ベストアンサー率0% (0/1)
回答No.2

コンパイラにより、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 ); }

A__
質問者

お礼

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

全文を見る
すると、全ての回答が全文表示されます。
  • ykkw_2001
  • ベストアンサー率26% (267/1014)
回答No.1

>atoi( ) の反対をやりたい  ANSI に、itoa(引数注意)があったと思いますが、だめなんでしょうか?

A__
質問者

お礼

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

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C++での、素数の表を作成するプログラムについての質問です。

    C++での、素数の表を作成するプログラムについての質問です。 配列を使用して、2~71までの素数を表に埋め込みたいのです。 プログラム本体はここまで出来ているのですが、 素数を求める計算の方法がイマイチわかりません。 #include<iostream> #include <iomanip> using namespace std; #define N 20 int main() { int arry[N]; /********************************* ここでforを用いた反復で計算を行う **********************************/ /********************* 配列変数の内容を出力 *********************/ for(int i=0;i<N;i++) cout << "+--" ; cout << "+\n" ; for(int i = 0; i < N; i++ ) cout << "|" << setw(2) << arry[i] ; cout << "|\n" ; for(int i = 0; i < N; i++ ) cout << "+--" ; cout << "+\n" ; return 0; } for文を使用した反復構造でarry[N]に2~71までの数字をいれていきたいです。 お願いします。 なお、 int arry[N]={2,3,5,7…} や arry[0]=2; arry[1]=3; arry[2]=5; …のように入力してはいけないのです。

  • C++の関数テンプレートで分からないところがあります。

    C++の関数テンプレートで分からないところがあります。 C++の入門書を読んで勉強しているのですが、その演習問題(答えはついてないです)で、以下のような問題がありました。 ----------------------------------------------------- 配列の全要素の最小値を求める関数テンプレートを作成せよ。 teplate <class Type> Type minof(const Type x[], int n); という形で作ること。 なお、最も小さい文字列を求められるようにするために、const char *型に明示的に特殊化したものも合わせて作成すること。 ------------------------------------------------ という問題なのですが、これにたいして僕は以下のように答えました。ヘッダのインクルードなどは省きます。 template<class Type> Type minof(const Type x[], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(x[min] < x[i])             min = i;     return x[min]; } template<> const char* minof<const char *>(const char x[][64], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(strcmp(x[min], x[i]) < 0)             min = i;     return x[min]; } int main() {     const int n = 5;     int a[n];     char s[n][64];     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> a[i];     }     cout << "文字列\n";     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> s[i];     }     cout << "整数の最小値---" << minof(a, n) << "です\n";     cout << "文字列の最小値---" << minof<const char *>(s, n) << "です\n"; } これをコンパイルすると、エラーで 明示的な特殊化; 'const char *minof<const char*>(const char [][64],const int)' は関数テンプレートの特殊化ではありません と 'minof' : 1 番目の引数を 'char [5][64]' から 'const char *const []' に変換できません。 とでてしまいます。 色々探してみたのですが、解決できませんでした・・。 特に最初のほうのエラーがよくわかりません。ちゃんと特殊化してる気はするのですが・・。 間違っている箇所の正当を載せていただけるとわかりやすくて、ありがたいです。 よろしくお願いします!

  • atoi関数の自作

    C言語でatoi関数を自作したのですが、正確な答えが出てきません 以下にソースを貼るのでどの当たりを直したらよいのかご教授願います。 1~9までの文字列を一つずつ配列に格納して変換する事を目的として作っています。 実行すると桁あふれしたような値が出てきてしまいます #include<stdio.h> #include<stdlib.h> int pow_10(int m) { int i,prod=1; for(i=0;i<m;i++){ prod=prod*10; } return prod; } ascii2int(char number[]){ int i,j,n[10],num; if(!strcmp(number,"")){ printf("Null string\n"); exit(1); } i=0; while(n[i]!='\0'){ n[i]=n[i]-48; i++; } num=0; for(j=0;j<i;j++){ num=num+n[j]*pow_10(i-1-j); } return num; } main(){ char su[10]; for(;;){ printf("Enter an integar:"); gets(su); if(!strcmp("x",su)){ break; } printf("%d\n",ascii2int(su)); } }

  • C言語で内積、、、わかりません。

    C言語で内積、、、わかりません。 /* double配列 vecter1 のデータと double配列 vecter2 のデータ、 および、 vecter1,vecter2 の「要素数」を関数 naiseki_f に 引数として渡す。 関数 naiseki_f 内では、 vecter1 と vecter2 とによる 「double型の内積値」を計算し、その結果を戻り値とするものである。 main関数内では、関数naiseki_fで計算した「内積値」を printf表示させるプログラムを作成せよ。 */ /* 配列の合計を求める */ #include<stdio.h> double naiseki_f(const int vecter1[],const int vecter2[]); int main(void) { int i,kosuu=10; double vecter1[10]={0.5,0.48,0.54,0.32,0.32,0.46,0.88,0.45,0.90,0.23}; double vecter2[10]={0.24,0.34,0.26,0.78,0.43,0.67,0.88,0.95,0.45,0.75}; double a; a=naiseki_f(vecter1,vecter2); /* ベクトルの内積計算 */ for(i=0; i<kosuu; i++) printf("%5.3f %5.3f\n",vecter1[i],vecter2[i]); printf("内積=%8.3f\n",a); return (0); } /* 内積を計算 */ double naiseki_f(const int vecter1[],const int vecter2[]) { int i; double ###; ############; for(i=0 ; i<10 ; i++) ################# ; return (######); } かれこれ2時間くらい悩んでいるんですが 内積をどうやって計算するのか資料をみてもわかりません、、。 main関数内は自分が入力した部分もあるので多少間違ってるかもしれません。 よろしくお願いします。

  • 配列の練習問題

    #include<iostream> using namespace std; //count関数の宣言 int count(char str[], char ch); int main() { char str[100]; char ch; cout << "文字列を入力して下さい。\n"; cin >> str; cout << "文字列から探す文字を入力して下さい。\n"; cin >> ch; int c = count(str, ch); cout << str << "の中に" << ch << "は" << c << "個あります。\n"; return 0; } //count関数の定義 int count(char str[], char ch) { int i = 0; int c = 0; while (str[i]) { if (str[i] == ch) c++; i++; } return c; } こんにちは。 この問題の解答のプログラムの意味がイマイチ解らないので良かったら教えて下さい。 確認がてらに質問します。 よろしくお願いします。

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • 配列受け渡し

    要素数nであるint型配列xから値がkである要素の添え字を返却する関数(ただし、値がkである要素が存在しなければ-1を返却するものとし、そのような要素が複数存在する場合は、先頭側の最も小さい添え字を返却する)を作成しています。 #include<iostream.h> #include<iomanip.h> int search(int x[],int n,int k) { int i,j; int result=-1; for(i=0;i<n;i++){ if(x[i]==k){ result=i; return(result); } else return(-1); } } int main(void) { const int ninzu = 5; int height[ninzu]; cout << ninzu << "要素:\n"; int i; for (i = 0; i < ninzu; i++) { cout << setw(2) << i+1 << "番目:"; cin >> height[i]; } cout << "検索要素は?:"; int target; cin >> target; int result=search(height, ninzu, target); if(result==-1) cout<<"ないよ"<<endl; else cout<<result+1<<"番目が"<<target<<endl; return (0); } このようにしたのですが、うまくいきません。また、複数の要素が発生したときの返却の仕方がわかりません。 どなたかアドバイス等よろしくお願いします。

  • 添字範囲エラー送出とデストラクタについて

    添字範囲エラー送出とデストラクタについて 下記のように(1)SiZE=5,(2)num=6 を投入した場合、添字演算子[]関数で(3)添字範囲エラー送出(size=5,I=5)の時、 IdxRngErr例外を発生し、(4)デストラクタを呼んでcatch((5)catch (IntArray::IdxRngErr&)で捕捉される。 質問 IdxRngErr例外を発生により、デストラクタを呼ばれる理由を教えて頂きたい。 *********************************************************************************** main() { int size, num; cout << "要素数:"; cin >> size;   (1) 5を投入 cout << "データ数:"; cin >> num; 、 (2) 6を投入 f(size, num); return 0; }/ *************************************************************************************** //===== 整数配列クラス ======// class IntArray { int size; // 配列の要素数 int* vec; // 先頭要素へのポインタ ~IntArray() { delete[] vec; } // (4)デストラクタよりIdxRngErrがcatch(5)される。 int& operator[](int i) { // 添字演算子[] if (i < 0 || i >= size) throw IdxRngErr(this, i); (3)// 添字範囲エラー送出(size=5,I=5)の時, return vec[i]; } ******************************************************************************************* / //--- 要素数sizeの配列にnum個のデータを代入して表示 --// void f(int size, int num) { try { IntArray x(size); for (int i = 0; i < num; i++) { x[i] = i; cout << "x[" << i << "] = " << x[i] << '\n'; } }    (5)catch (IntArray::IdxRngErr& x) { cout << "添字オーバフロー:" << x.Index() << '\n'; return; i

  • C言語のプログラムについて。

    C言語のプログラミングについて質問です。 入力されたデータの配列とデータ数を渡すと配列に格納された値を逆順にして、格納し直す関数reverse関数を書き結果を出力せよ、というものなのですが下のように書いたのですが、うまく作動しません。どこがいけないのでしょうか...?教えていただきたいです。 #include <stdio.h> void reverse(int *data[], int n); #define MAX 100 int main() { int data[MAX]; int n, i; scanf("%d", &n); if (n >= MAX) n = MAX; for (i = 0; i < n; i ++){ scanf("%d", &data[i]); } reverse(data, n); for (i = 0; i < n; i ++) { printf("%d\n", data[i]); } return 0; } void reverse(int *data[], int n) { int c, i; for (i = 0; i < n; i ++) { c = *data[i]; *data[i] = *data[n - (i + 1)]; *data[n - (i + 1)] = c; } }

  • char型変数のアドレスを coutで表示するには

    #include <iostream> using namespace std; int main() { bool b; int i; short s; long l; float f; double d; char c; //上で宣言した変数のアドレスを表示 cout << "bool &b " << &b << endl; cout << "int &i " << &i << endl; cout << "short &s " << &s << endl; cout << "long &l " << &l << endl; cout << "float &f " << &f << endl; cout << "double &d " << &d << endl; cout << "char &c " << &c << endl; //「char &c 」とのみ表示される cout << '\n'; //char型のみ printf で再表示 printf("char &c %p\n", &c); //「char &c ********」と表示される return 0; } 上のプログラムを実行すると cout << "char &c " << &c << endl; のところだけ、アドレスが表示されません。 printfを使えば、char型の変数のアドレスも表示されるのですが…。 coutを使ってchar型のアドレスを表示させるにはどうすればいいのでしょうか。 よろしくお願いします。

このQ&Aのポイント
  • 脂肪が筋肉に変わることはないと思います。
  • ダイエット中の女30代がダンスとストレッチをしても見た目の変化がないという悩みがあります。
  • 足が筋肉質になったように感じるが、細くなったというより太くなった様に見られると言われることにショックを受け、細くなりたいという質問をしています。
回答を見る

専門家に質問してみよう