C では、列挙型は名前付き定数のセットを表す便利な方法を提供します。ただし、列挙値を出力するときのデフォルトの動作は、その数値表現を表示することです。
次のような列挙型があるとします。
enum Errors { ErrorA = 0, ErrorB, ErrorC, };
次を使用して列挙値を出力しようとすると、 std::cout:
Errors anError = ErrorA; std::cout << anError; // 0 will be printed
テキスト表現の代わりに数値 0 を取得します。 「エラーA」。この問題は、std::cout に列挙型を文字列に変換するためのサポートが組み込まれていないために発生します。
1。マップの使用
1 つの方法は、各列挙値をテキスト表現に関連付けるマップを作成することです。
#include <map> #include <string_view> std::ostream& operator<<(std::ostream& out, const Errors value) { static const auto strings = [] { std::map<Errors, std::string_view> result; #define INSERT_ELEMENT(p) result.emplace(p, #p); INSERT_ELEMENT(ErrorA); INSERT_ELEMENT(ErrorB); INSERT_ELEMENT(ErrorC); #undef INSERT_ELEMENT return result; }; return out << strings[value]; }
2.線形検索で構造体の配列を使用する
もう 1 つのオプションは、それぞれ列挙値とそのテキスト表現を含む構造体の配列を使用して、線形検索を実行することです。
#include <string_view> std::ostream& operator<<(std::ostream& out, const Errors value) { #define MAPENTRY(p) {p, #p} const struct MapEntry { Errors value; std::string_view str; } entries[] = { MAPENTRY(ErrorA), MAPENTRY(ErrorB), MAPENTRY(ErrorC), {ErrorA, 0} //doesn't matter what is used instead of ErrorA here... }; #undef MAPENTRY const char* s = 0; for (const MapEntry* i = entries; i->str; i++) { if (i->value == value) { s = i->str; break; } } return out << s; }
3. switch/case の使用
最後に、switch/case ステートメントも使用できます:
#include <string> std::ostream& operator<<(std::ostream& out, const Errors value) { return out << [value] { #define PROCESS_VAL(p) case(p): return #p; switch(value) { PROCESS_VAL(ErrorA); PROCESS_VAL(ErrorB); PROCESS_VAL(ErrorC); } #undef PROCESS_VAL }; }
ソリューションのテスト:
これらのソリューションをテストするには、次のコマンドを使用して実行可能ファイルを作成します。コード:
#include <iostream> int main(int argc, char** argv) { std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl; return 0; }
この実行可能ファイルを実行すると、列挙値のテキスト表現が出力されます:
ErrorA ErrorB ErrorC
以上がif/switch ステートメントを使用せずに C 列挙値をテキストとして出力する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。