intからchar *に変換する方法


97

私が知る唯一の方法は:

#include <sstream>
#include <string.h>
using namespace std;

int main() {
  int number=33;
  stringstream strs;
  strs << number;
  string temp_str = strs.str();
  char* char_type = (char*) temp_str.c_str();
}

しかし、タイピングが少ない方法はありますか?


8
なぜC ++文字列ではなくC文字列が必要なのですか?
KillianDS

回答:


127
  • C ++ 17では、次のように使用std::to_charsします。

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
  • C ++ 11では、次のように使用std::to_stringします。

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
  • C ++ 03では、次のように使用する以外はconst、問題ありません。

    char const* pchar = temp_str.c_str(); //dont use cast

1
最初の部分は実際には質問に答えていません(ただし、その機能を知らなかったので、役立つ情報として役立ちます)
jcoder

1
Better :)さらに、c ++ 11についてもう一度読んでみます。大きな機能については知っていますが、これにより、見逃した小さな機能のほうが多いことがわかりました。
jcoder

1
@Adambean:なぜ「std :: stringを使用すべきでない」のですか?。std::stringデフォルトではなく、を使用する必要がありますchar*
Nawaz

1
std :: stringは、特に古いプロジェクトでは、常に使用できるとは限りません。多くのC ++ゲームもstd :: stringから離れています。intからstd :: stringからchar *への移行は、intからchar *への移行と同じではありません。
アダムビーン2016年

1
@Adambean:C ++の場合std::string、質問自体で明示的に指定されていない限り、デフォルトで使用可能であると想定します。理にかなっていますか?また、質問自体がstd::string(およびstd::stringstream)を使用しているため、それに同意する理由はあまりありません。
Nawaz

11

私はあなたがsprintfを使うことができると思います:

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);

1
char *をcharに変更する必要があります。現在、numberstringはポインタの配列です
josefx

1
また、32ビット整数をnullで終了するbase-10表現に変換するには、12文字が必要です。10では十分ではありません-2147483647
スティーブジェソップ2012年

11
説明はどうですか?(((sizeof number) * CHAR_BIT) + 2)/3 + 2魔法のように見える...
マイクS

7

あなたはブーストを使うことができます

#include <boost/lexical_cast.hpp>
string s = boost::lexical_cast<string>( number );

5

Cスタイルの解決策はを使用することitoaですが、より良い方法はsprintf/snprintfを使用してこの数値を文字列に出力することです。この質問を確認してください:移植性のある整数を文字列に変換する方法?

itoa関数はANSI-Cで定義されておらず、C ++の一部ではありませんが、一部のコンパイラでサポートされていることに注意してくださいこれは非標準の関数であるため、使用しないでください。この質問もチェックしてください:整数を文字列C ++に変換するためのitoa()の代替?

また、C ++でのプログラミング中にCスタイルのコードを書くことは悪い習慣と見なされ、「恐ろしいスタイル」と呼ばれることもあります。本当にCスタイルのchar*文字列に変換しますか?:)


5

理由があるので、私は最後の行のconstを型キャストしません。const char *を使用できない場合は、次のようにchar配列をコピーすることをお勧めします。

char* char_type = new char[temp_str.length()];
strcpy(char_type, temp_str.c_str());

もしかしてconst char* char_type = temp_str.c_str();良いですか?
rsk82

1
はい。c_strは、文字列オブジェクトの内部バッファへのポインタを提供します。constをキャストする場合、あなたまたは別のプログラマーは、非const変数を介してバッファーを変更してもよいと考えるかもしれません。そうではありません。元の文字列オブジェクトは、これらの変更について何も知りません。一方、文字列はまだバッファを所有しています。文字列オブジェクトがスコープ外になると、ポインタの背後にあるメモリが文字列オブジェクトデストラクタによって削除され、ぶら下がりポインタが残ります。コピー操作は両方の問題を取り除きます。
user331471

1
またはstd::vector<char> temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];。これは可変メモリを提供しますが、もちろん、ポインタを使用したい限り、ベクトルを存続させる必要があります。
スティーブジェソップ2012年

1
または単に使用stringしてchar *、古くてプレーンなCからの古くてプレーンな愚かなことに気をつけないでください。<意図した炎の
断片

@Griwes:問題はchar*、「C ++からCで記述された既存のライブラリを呼び出すポイントがあるのか​​、それともC ++で再実装する必要があるのか​​」ではなく、にアクセスする方法です。;-p
スティーブジェソップ

2

さて、最初に、この質問がすることを実行する何かが必要でしたが、私はそれを速く必要としました!残念ながら、「より良い」方法は600行近いコードです!!! それが何をしているかとは何の関係もないその名前を許してください。適切な名前はInteger64ToCharArray(int64_t value)でした。

https://github.com/JeremyDX/All-Language-Testing-Code/blob/master/C%2B%2B%20Examples/IntegerToCharArrayTesting.cpp

パフォーマンスを妨げずに、そのコードをクリーンアップしてみてください。

入力:最小から最大の範囲の任意の符号付き64ビット値。

例:

std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MAX) << '\n';
std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MIN) << '\n';

出力:

Test: 9223372036854775807
Test: -9223372036854775808

元の速度テスト:(Integer64ToCharArray();

ベストケースの1桁の値。

ループ:100,000,000、使用時間:1,381(ミリ)、ループあたりの時間13(ナノ)

最悪のケース20桁の値。

ループ:100,000,000、使用時間:22,656(ミリ)、ループあたりの時間226(ナノ)

新しい設計速度テスト:(AddDynamicallyToBuffer();

ベストケースの1桁の値。

ループ:100,000,000、使用時間:427(ミリ)、ループあたりの時間4(ナノ)

32ビットの最悪のケース-11桁の値。

ループ:100,000,000、使用時間:1,991(ミリ)、ループあたりの時間19(ナノ)

負の1兆の最悪のケース-14桁の値。

ループ:100,000,000、使用時間:5,681(ミリ)、ループあたりの時間56(ナノ)

64ビットワースケース-20桁の値。

ループ:100,000,000、使用時間:13,148(ミリ)、ループあたりの時間131(ナノ)

使い方!

分割統治テクニックを実行し、文字列の最大長になったら、各文字の値を個別に設定します。上記の速度テストに示されているように、長さが長いほどパフォーマンスが大幅に低下しますが、元のループメソッドよりもはるかに速く、2つのメソッド間で実際にコードが変更されておらず、ループは使用されていません。

私の使用法では、このため、代わりにオフセットを返し、char配列のバッファーを編集せず、頂点データの更新を開始し、関数にオフセットの追加パラメーターがあるため、-1に初期化されません。




弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.