1

基本的な質問:

データをストーリー化/変更している場合、ハードコードされたインデックスを使用してファイルの要素にアクセスする必要がありますtargetFile.getElement(5)。ハードコードされた識別子 (内部的にインデックスに変換されます) を介して、つまりtarget.getElementWithID("Desired Element")、または何らかの中間DESIRED_ELEMENT = 5; ... target.getElement(DESIRED_ELEMENT)の などを使用します。

編集:またはenum??を使用したもの


バックグラウンド:

私のプログラム (c++) は、多くの異なる'dataFile'sにデータを格納します。また、すべてのデータ ファイルのリストを別のファイル( 「listFile」)に保持しています。これには、それぞれのプロパティの一部も格納されています (以下を参照してください。ただし、名前は何行で、何行の情報がなど)。データファイルとリストファイルを管理するオブジェクトがあり、それを「fileKeeper」と呼びます。

listFile のエントリは次のようになります。

filename , contents name , number of lines , some more numbers ...

このリストにフィールドを追加/削除する可能性は間違いなくありますが、一般的には静的なままです。

現在、次のような各エントリの各要素の ID を保持する定数文字列配列があります。

const string fileKeeper::idKeys[] = { "FileName" , "Contents" , "NumLines" ... };
const int fileKeeper::idKeysNum = 6;   // 6 - for example

私はこれを「良い」プログラム形式で管理しようとしています。したがって、ファイル内の行数を取得したい場合(たとえば)、「3番目の要素を取得するだけのメソッドを使用する代わりに...代わりに、次のようなことを行います:

string desiredID = "NumLines";
int desiredIndex = indexForID(desiredID);
string desiredElement = elementForIndex(desiredIndex);

ここで、関数indexForID()は のエントリを調べidKeysて、見つかっdesiredIDた後、対応するインデックスを返します。そしてelementForIndex(index)実際にlistFileに入り、カンマ区切りの文字列の index 番目の要素を取得します。


問題:

これはまだかなり醜い/貧弱な形のようです。これを行う方法はありますか?そうでない場合、これが通常行われる一般的な方法は何ですか?

ありがとう!

4

4 に答える 4

1

文字列をキーとして使用する方法が好きです。を使用して、文字列を数値にマップできますstd::map<string, int>。その後、次のことができます

std::map<string, int> columns;
columns["FileName"] = 0;    
columns["Contents"] = 1;
columns["NumLines"] = 2;

columns["Contents"]次に、たとえば を参照して、列 ID を取得できます。キーのスペルを間違えた場合に通知する関数を使用して行うのが最善です。次のようなコード:

std::map<string, int>::iterator it = columns.find(key);
if (it == columns.end()) { // key not in columns
    // report error here
于 2012-12-16T08:54:28.250 に答える
1

どちらも、データベースを使用することも、少なくとも csv を使用することもありません。Sqlite は軽量のサーバーレス データベースであり、バインディングはほぼすべての言語で利用できます。これは、大量のデータを保存する必要があるが、データベース サーバーをインストールして構成する必要がない、この種のシナリオ向けに正確に設計されています。おそらく何らかの ORM を使用して、データを保持するための構造体/クラスを作成することもできます。

csv を使用していて、列の順序を並べ替える機能が必要な場合は、列名をファイルの最初のエントリとして保存します。ほとんどの csv ライブラリは、最初の列を列名として使用できるはずです。

于 2012-12-16T11:01:12.843 に答える
0

最初にFilePropertyクラスを作成するlistFileと、このクラスのオブジェクトのリストになり、「キー」はこのクラスのメンバー変数になります。

于 2012-12-16T08:31:07.723 に答える
0

私の解決策は、std::map と列挙型の組み合わせを使用しています。

class FileKeeper {
    public:
        enum ID_KEY = { FileName , Contents , "Num_Lines };
        string getIDKey(ID_KEY idk);

    private:
        static map<int,string> ID_Key = { { FileName, "Filename" }, { Contents, "Contents" }, { Num_Lines, "Num Lines" } };

}

string FileKeeper::getIDKey(ID_KEY idk) {
    if( idk > 0 && idk < ID_Key.size() ) { return ID_Key[idk]; }
    else { return ""; }
}

このようにして、列挙型を使用してインデックスに簡単にアクセスし、キーを簡単に (適切な順序で --- これmap<string,int>は実行しません) 反復処理し、マップを使用してインデックスから文字列へのマッピングを取得できます。get()メソッドを使用すると、マップに要素を追加できなくなり、実際のmapプライベートを保持することで、整数を使用して遅延アクセスすることができなくなります (技術的には int-index 型ですが)。

get___("Num Lines"); など、識別された実際の文字列を使用して要素にアクセスする必要があるコードの場所はありません。--- これはちょっと醜く、偽物のようです。

于 2012-12-19T22:26:16.727 に答える