web-dev-qa-db-ja.com

C ++で定数std :: stringをうまく使う方法

現在のコードプロジェクトには、エラーメッセージを出力するために使用する定数文字列が非常にたくさんあります。

このような文字列をハードコーディングすることは、一般的に悪い習慣と見なされています。現在、これらの文字列をプログラムに含める「クリーンな方法」を探しています。したがって、次のような「constants.h」と「constants.cpp」を作成しました

#ifndef CONSTANTS_H_
#define CONSTANTS_H_

extern std::string error_message_1;

#endif

そしてconstants.cpp:

#include "constants.h"

std::string error_message_1 = "this is just a sample, not my actual naming convention. move on the the question ;-)"

したがって、私がこれで抱えている問題を目にするかもしれません。多くのエラーメッセージが原因で、変数名自体はかなり長いです。エラーメッセージはさらに長くなるため、1行のコードで標準の80文字がクラッシュします。

明らかに私は自分のコードをすてきでクリーンなものにしたいと思っています。コードの1行あたり80文字をはるかに超えるのは好きではありません。次のようなものは好きではありません。

std::string error_message_1 = "this is just a sample about how to"
                              " have one string across many lines"
                              " in the source code. this is not "
                              "very pretty too..";
std::string msg = "and suddenly there's one line which is good..";
std::string error_message_with_longer_name = "and it's even "
                                             "uglier with not "
                                             "equally long "
                                             "variable names";

プログラムの開始時に読み込まれる外部ファイルに文字列を格納することも、コンパイラが不足している文字列について警告できないため、最適ではないようです。基本的にこれは維持するのが面倒です。

それで、あなたはそれについて何をしますか? Android(または一般的にJava全般))開発について知っている「リソース」のような素晴らしいものはありますか?

注:私の命名規則が悪いことを教えないでください。上記は一例です。それはそれがどのように見えるかではありません;-)

5
stefan

このような文字列をハードコーディングすることは、一般的に悪い習慣と見なされています。

よくわかりません。

文字列リテラルは、文字列の名前よりも読みやすいです。複数の場所に同じテキストが必要な場合は、テキストを関数にカプセル化し、単一の関数を呼び出してメッセージを表示します。

テキストを1つのファイルにまとめたい場合。次に、あなたが探しているものは、すべての文字列リテラルを文字列変数に手動で移動しないリソースとしての文字列です。

次のパッケージをチェックアウトします(通常、ローカライズで使用されますが、ここで機能します)。

* gettext

基本的に、このパッケージの機能は、コードに「英語」バージョンのメッセージを残すことです。しかし、「英語」のテキストをリソーステーブルへのキーとして使用して、特定のローカルの文字列の正しいバージョンを取得します。

したがって、次のようなコード:

printf ("and suddenly there's one line which is good..");

// Now looks like this:

printf (gettext ("and suddenly there's one line which is good.."));

すべての定数文字列を別のパッケージに抽出する手間をかける必要はありません。

詳細については、こちらをご覧ください。 http://www.gnu.org/software/gettext/

個人的には、ローカライズのために上記を boost format ライブラリと組み合わせて使用​​しています。

std::cout << boost::formt("The time is %1 in %2.") % time % country;

becomes:

std::cout << boost::formt(gettext("The time is %1 in %2.")) % time % country;

English Resource File:      "The time is %1 in %2."
Azerbaijani Resource File:  "Saat %2 saat %1 deyil."
7
Martin York

このような文字列をハードコーディングすることは、一般的に悪い習慣と見なされています

リテラルを含むファイルがハードコーディングされていることに気付いていますか?ハードコーディングをマジックナンバーと混同しているようです。一般に、文字列は不思議なものではないため、名前を付ける必要はありません。それらを定数に移動することは、重複を避けるためにのみ必要です。 (ほとんどのエラーメッセージの場合のように)文字列を1回だけ使用している場合は、何らかの理由でコンパイル時の構成ファイルとして実行しているのでない限り、それらを別のファイルに移動しても意味がありません。

ユーザーがエラーメッセージを変更できることが重要な場合は、エラーメッセージを(.hppではなく)構成ファイルに移動します。

翻訳に必要な場合は、 gettext のようなものを使用します。これにより、翻訳ファイルを提供し、ソースをクリーンに保つことができます。

また、文字列定数式にはstd::stringを使用しないでください。代わりにconst char[]を使用してください。

5
Pubby

文字列をハードコーディングしても、値を変更する必要がない場合は問題ありません。私はそれらが静的なconstとして格納され、関連する列挙型であると何度も言及しているのを見てきました。

インターフェイスを簡単にしたい場合は、クラスにラップできます。

ただし、これを行うために言語に組み込まれたものは実際にはありません。これは、言語を使用して行ったものです。

0
Stefan