• ベストアンサー

enumの値から定義名を文字列化したい

C++でenumの値を元に、定義した名前(Fruits_Appleとか)を文字列として取得したいのですが、何か良い方法はないでしょうか? switch文等で分岐させて...という方法もありますが、enumの定義数が多くなるとコードが複雑になるので、シンプルな方法をさがしています。 enum Fruits{ Fruits_Apple, Fruits_Orange, Fruits_End }; void printFruits(Fruits fruits) { // ここで引数fruitsの値に応じて"Fruits_Apple"とか"Fruits_Orange"とかを // 文字列に代入したい std::string fruitsName = "Fruits_Apple"; }

  • goom0
  • お礼率25% (2/8)

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

  • ベストアンサー
回答No.4

 こんばんは。  例えば、boostライブラリのメタプリプロセッサの如く、可視性など関係なしに手段を選ばなければナンボでも出来ます。  ただし一回でも陥ると地獄そのものです。 //------------------------------------------------------------------------------------- //misc.hpp //------------------------------------------------------------------------------------- #ifndef __MISC_HPP__ #define __MISC_HPP__ # define ArrayCount(a) (sizeof(a)/sizeof(a[0])) # define ArrayEnd(a) (a + ArrayCount(a)) #endif //------------------------------------------------------------------------------------- //misc.hpp //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- //fruits.hpp //------------------------------------------------------------------------------------- #include"misc.hpp" //enumを作成する #ifdef MAKEENUM # define MAKEHDR(name) enum name { # define MAKELINE(name) name # define MAKEFTR(name) }; //arr##name##Pair[]を作成して、map##name##Resultに入れる #else # define MAKEHDR(name) std::pair<name, std::string> arr##name##Pair[] = { # define MAKELINE(name) std::make_pair(name, std::string(#name)) # define MAKEFTR(name) }; \ std::map<name, std::string> map##name##Result;\ {for(size_t n = 0; n < ArrayCount(arr##name##Pair); ++n)map##name##Result.insert(arr##name##Pair[n]);} #endif MAKEHDR(Fruits) MAKELINE(Fruits_Apple), MAKELINE(Fruits_Orange), MAKELINE(Fruits_End) MAKEFTR(Fruits) MAKEHDR(Gender) MAKELINE(Gender_Male), MAKELINE(Gender_Female), MAKELINE(Gender_End) MAKEFTR(Gender) #undef MAKEHDR #undef MAKELINE #undef MAKEFTR #undef MAKEENUM //------------------------------------------------------------------------------------- //fruits.hpp //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- //test.cpp //------------------------------------------------------------------------------------- #include<map> #include<string> #include<iostream> //enumの作成 #define MAKEENUM #include"fruits.hpp" static void Print(Fruits fruits, Gender gender) { //map##name##Resultの作成 #include"fruits.hpp" std::cout << mapFruitsResult[fruits] << std::endl; std::cout << mapGenderResult[gender] << std::endl; } int main() { ::Print(Fruits_Apple, Gender_Female); return 0; } //------------------------------------------------------------------------------------- //test.cpp //-------------------------------------------------------------------------------------

その他の回答 (3)

回答No.3

enum は コンパイルの時点で解決されることが多いので 地道にやるしかないですね。 要は名前に変換できればいいんですよね。 C++ならstd::mapを準備してあげるのが無難なのかなー? 僕なら、静的な配列と取得関数を作るけど。。。(C99) # 下はコンパイルしていないので文法ちょっと違うかも ----xxx.h enum Fruits { Fruits_Apple, Fruits_Orange, NumberOfFruits }; extern const char * getNameByFruits( const Fruits n ); ----xxx.c const char * getNameByFruitsIX( const Fruits n ) { static const char *FruitsName[NumberOfFruits] = { [Fruits_Apple] = "りんご", [Fruits_Orange] = "みかん", } if( n < NumberOfFruits ) return FruitsName[n]; return ""; }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

マクロを駆使しつつ, map で変換関数でも書くかな. 例えば DeclareFruitMember(Apple) DeclareFruitMember(Orange) ... #undef DeclareFruitMember と書かれたファイルを作って, enum Fruits { #define DeclareFruitMember(mem) Fruits_##mem, #include "それ" }; std::pair<enum Fruits, std::string> fruitMemberStrings[] = { #define DeclareFruitMember(mem) { Fruits_##mem, "Fruits_" #mem }, #include "それ" }; std::map<enum Fruits, std::string> fruitMemberMap(fruitsMemberStrings, fruitsMemberStrings+要素数); みたいに.

  • MrBan
  • ベストアンサー率53% (331/615)
回答No.1

マクロ(define)からならこんなことはできますけど… #define APPLE 0 #define TO_STR(str) #str TO_STR(APPLE) 残念ながらenumからはないんじゃないですかね。(あれば知りたい) # 無理矢理派生クラスで独自enum風クラスを作って、 # typeid().name()をつかって…とか考えると、 # 素直に変換関数を書いた方がよほどシンプルだと思いますし。 # もしくは、(独自)プリプロセッサをかませるか。

関連するQ&A

  • enum列挙子に使える文字列と使えない文字列

    enum Ok{A,A,月1,月1,_,?} enum Ng{1月,1月,→,!,☆} public class Main{public static void main(String[] args){ System.out.println("あああああ"); }}//終わり このJavaプログラムはエラーになります。何故ですか? 要するに、enumに使える列挙子の法則性に興味があります。「?」は通って「!」はエラーって、コンパイルを試みた後に結果を知ると、色々とムカつきます。 「!」は通って「?」はエラーだと嘘が書物に書いてあると、騙されます。 enumで使える列挙子(要素)のタイプが載ってるサイト、enumの列挙子に使うとエラーになってしまう例が載ってるサイトなどを紹介してくれるとありがたいです。 どんな文字列でもenumに使えて、何でもOKなら親切だと思うのに・・・

    • ベストアンサー
    • Java
  • C言語におけるenum型

    enum word{apple banana orange}; enum word w; と定義します。 scanfなどでキーボード入力から"apple"などを入力したとします。 この入力文字を変数wに格納(列挙型 で定義されている整数値を格納)するには どのようにしたらいいですか?

  • C言語で取得した文字列を、C++の文字列として取り扱いたいです。

    C言語で取得した文字列を、C++の文字列として取り扱いたいです。 皆さんこんにちは。 C言語で取得したchar型で定義された文字列を、 C++の「std::string」に渡したいと思っております。 どうすればかなうでしょうか? 具体的には次のような内容です。 ■C言語側 ---- char key1 = "deperture"; ---- ■C++側で「key1 = key2」としたいです。 ---- std::string key2 = key1; ---- C言語側で記述されている「key1」の値(deperture)を、 C++ソース内の「key2」に渡したいと思っています。 こうゆう場合、どんな方法をとれば適切でしょうか。 C言語側でのchar型の文字列の値を、 C++側の「std::string」型として C++のソースへ渡す方法が分からないです。 アドバイスいただけるとありがたいです。 簡単な例を頂けると更に大変ありがたいです。 以上どうぞ宜しくお願い致します。

  • ENUM列に列挙されていない値を挿入しようとしたときエラーにすることは

    ENUM列に列挙されていない値を挿入しようとしたときエラーにすることはできますか 例えば、 ENUM('-10', '-5', 'なし', '+5', '+10') と定義した列に対して、'+2'を挿入しようとした場合はエラーにしたいです。 現状では、'+2'を挿入しようとすると、2番目の値と解釈され、'-5'が挿入されてしまうようです。 バッチ処理が、やっとこさ終わったと思いきや、データを確認してみてビックリですx_x

    • ベストアンサー
    • MySQL
  • C側で得た変数をC++の変数に流し込みたいです。

    C側で得た変数をC++の変数に流し込みたいです。 現在、C++で 次のように、 入力ストリームから1行分の文字列を読み込んで、 読み込んだ文字列を「cmd」に流し込んだ際に、 cmdに代入された文字列が「get」であると、 他のファイルで定義されている「doget」という関数が 実行されるようになっています。 ----------- std::string cmd; std::getline(cin, cmd); void nod::execute(const std::string& cmd) { std::stringstream ss(cmd); std::string command; ss >> command; if (command == "get") { std::string key = "baseball" ; std::string val = stand.doget(key); } } ----------- これを、 以下のように、 (1) C言語側にある「a」という変数にある値を C++側のkeyに流しこんで、 (2) また、C側にあるsign配列内の文字列を C++側の「cmd」に代入したいと思っています。 C側 --------- /* C側の「a」配列の値を、上記C++側の「key」に代入したい */ char a[] = "www.gehohogetest.jp"; /* 上記C++側の「cmd」変数に、C側の配列で定義されている"get"という文字列を代入したい */ char sign[]= "get"; --------- その場合、C側とC+側をどう記述すれば、 希望を叶えることが出来るでしょうか。 アドバイスいただけるとありがたいです。 以上どうぞ宜しくお願い致します。

  • 複数の列にまたがってユニーク制約をかけたい

    MySQLでDBを設計しているのですが、 テーブルを作成するさい、1つの列についてユニークな制約をつくる方法は分かるのですが、 2つの列について(仮に、fruit,countryとします)、 「fruit,country」の値がともに一致するような列は許さない、というようなユニークな制約は実現可能でしょうか? つまり・・・・ fruit | country ------------------- apple | japan apple | uk banana | japan orange | uk orange | china 上記は、fruit列だけを見ると、重複しているところがあり、 country列だけを見ると、重複しているところがありますが、 両方とも一致する行は存在しないのでOKです。 で、ここに、 fruitにapple, countryにukという値を入れようとすると、すでに、2行目に同じペアの行が存在するので、 エラーにしたいというわけです。 もし可能ならどうやってかけばいいのでしょうか? どうぞよろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • 文字列と整数型について

    はじめまして。 どうしても困っているのでヒントでも良いのでおねがいします。 関数内(func1)で確保した文字列変数のポインタを 別の関数(func2)にポインタ渡しします。 func2内で整数型で計算した結果を引数で示された文字列変数に 代入するというようなことをしたいと思ってます。 ここで、intは4byteとします。 メモリ長だけで見ると、bit[4] = tmp です。 void func1(){ char bit[4]; func2(bit); return; } void func2(char* p){ int tmp = 0x10101100; p = tmp; <---- ??? return; } そこでどのようにすれば、 代入することができるのか分かりません。 以下のような結果になるように代入したいと思っています。 bit[0] = 0x10; bit[1] = 0x10; bit[2] = 0x11; bit[3] = 0x00; 小さな文字列型に整数型をどのように渡せばよいのかが 一番疑問に思っているところです。 整数型に文字列型を代入する場合には 文字列のバイト指定とシフト演算で実現できています。 ヒントでもよいのでお願いします。

  • 文字列の動的な結合

    C♯、.net frameworkdは2.0の環境です。 メソッドでSQL用の文字列を作っています。 引数によって、JOINするテーブルを変えたいのですが、StringBuilderではなく、 単なるStringの変数を、ひたすら + で結合している状態なので、悩んでいます。 String sql; sql = " select " + " tbl.column1 " + " from " + … こんな感じです。 StringBuilderで作り直したいのですが、諸事情により難しいので、+での文字列結合をしつつ、 ところどころ、引数を見て文字列を結合したりしなかったり…ということをスムーズにできる 方法はないでしょうか?

  • VC++2005で文字列変数の定義ができない

    VC++2005Express Edtionで文字列を扱うにはどうやればよいのでしょうか? 文字列変数を定義して、それに文字を代入して、 System::Diagnostics::Debug::Printするサンプルコードを提示してもらえないでしょうか?

  • 【C++/CLI】文字列管理関数の作成

    VC++2005の.NET、言語はC++/CLIでアプリを作成しています。 String型の文字列を管理するクラスを作成しようと思います。 自分ではどのようなものを作成したいのか、イメージはついているのですが、 CLIの知識、技術が足りず、なかなか作成することが難しい状態です。 下記にイメージを記載しますので、有識者の方々アドバイス頂けませんでしょうか。 よろしくお願い致します。 文字列管理クラス「TextTbl」 【TextTbl.h】 enum { STR_TEST1, //格納したい文字列1のID STR_TEST2 //格納したい文字列2のID // ・・・   //ここに追加したい文字列のIDを追加していく } String^ getText( int id ); 【TextTbl.cpp】 // 文字列を取得する関数(引数は文字列のID) String^ TextTbl::getText( int id ) { //文字列のテーブルを定義する処理(文字列IDと文字列の文言が対になって定義されている) //IDを元に文字列を検索し取得する処理 return str; //検索した結果のString型文字列を返す }