0
struct DataValue
{
    DataValue() : uiQuality(0) {} // Here 0 stands for good.
    unsigned int    uiQuality;
    std::string     timeChanged;
    float           value;
};

std::vector<DataValues> myDataValues

アプリケーションのある時点で、ベクターのデータがいっぱいになります。以下を使用してファイルに書き込んでいます。

std::ofstream myfile("myData.txt", std::ios::app);

for (int j = 0; j < myDataValues.size(); j++)
{
    std::string quality;
    if(myDataValues[j].quality == 0) {
        quality = "good";
    }
    else {
        quality = "bad";
    }
    myfile << myDataValues[j].timeChanged.c_str() << "  " <<  myDataValues[j].value  << "  " <<  quality << std::endl; 
}

ファイルは以下のようになります。

2012-06-25 12:41:56.789  55  good
2012-06-25 12:51:14.782  55  good
2012-06-25 05:25:16.456  62.6925  good
2012-06-25 05:26:11.458  63.4109  good
2012-06-25 05:27:01.459  63.0383  good
2012-06-25 05:27:56.959  61.5266  good
2012-06-25 05:29:01.959  58.5354  good
2012-06-25 05:32:06.963  47.5656  good
2012-06-25 05:33:06.964  44.9916  good
2012-06-25 05:33:11.963  44.8267  good
2012-06-25 05:34:06.965  43.6011  good
2012-06-25 05:34:56.965  43.493  good
2012-06-25 12:51:14.782  52.418  good
2012-06-25 09:49:54.112  0  good
2012-06-25 11:50:30.781  0  good

次に、他のアプリケーションで上記のファイルを読み取り、たとえば別のベクトルを入力する必要があります。ベクトルが重複しているかどうかに関係なく、このチェックは必要ありません。

 std::vector<DataValues> anotherDataValues

サンプルコードをリクエストする上記のファイルからデータを読み取り、上記のベクトルを入力するにはどうすればよいですか?

これを効果的に行うにはどうすればよいですか。

お手数をおかけしますが、よろしくお願いいたします。

4

3 に答える 3

2

明らかなアプローチは、クラスの>>(および<<)演算子を作成することです。挿入演算子は非常に簡単です。

std::ostream&
operator<<( std::ostream& dest, DataValue const& data )
{
    dest << data.timeChanged << "  "
         << data.value << "  "
         << (data.uiQuality == 0 ? "good" : "bad");
    return dest;
}

これを実行したら、次のように記述するだけで配列を出力できます。

std::copy( myDataValues.begin(), myDataValues.end(),
           std::ostream_iterator<DataValue>( myFile, "\n" ) );

フォーマットで発生する可能性の<<あるエラーに対処する必要があるため、演算子は少し注意が必要です。データ形式にスペースが含まれているとすると、ターミネータとして「\ n」を課し、次のようにします。

std::istream&
operator>>( std::istream& source, DataValue& dest )
{
    std::string line;
    if ( std::getline( source, line ) ) {
        std::istringstream parse( line );
        std::string date;
        std::string time;
        float value;
        std::string status;
        parse >> date >> time >> value >> status >> std::ws;
        if ( ! parse || (status != "good" && status != "bad") ) {
            source.setstate( std::ios_base::failbit );
        } else {
            dest.timeChanged = date + ' ' + time;
            dest.value = value;
            dest.uiQuality = (status == "good" ? 0 : 1);
        }
    }
    return source;
}

日付形式の空白は物事を複雑にすることに注意してください。あなたがフォーマットをある程度コントロールできれば、私はそれを取り除くでしょう。(たとえば、ISOは'T' 日付と時刻を区切るためにを使用します。)とにかく、ある種のクラスを使用することは理にDataTimeかなっています。もちろん、このクラスは独自の>>とを提供<<し、上記で使用できます。

これを行うと、読むことも簡単になります。

std::vector<DataValue> v(
    (std::istream_iterator<DataValue>( myFile )),
    (std::istream_iterator<DataValue>()) );

(余分な括弧に注意してください。最も厄介な解析問題を回避するために、少なくとも1つの引数に必要です。)

于 2012-06-26T08:18:23.343 に答える
1

最初に、 1つのDataValueオブジェクトを読み取る方法を理解する必要があります。次に、それらのベクトルを埋めるのは簡単です。これを行う方法は次のとおりです(ただし、おそらくより包括的なエラーチェックを提供する必要があります)。

std::istream & operator>>(std::istream & is, DataValue & dv) {
    std::string date, time, quality;
    float value;
    if (is >> date >> time >> value >> quality) {
        if (quality == "good")
            dv.uiQuality = 0;
        else if (quality == "bad")
            dv.uiQuality = 1;
        else {
            is.setstate(std::ios::failbit);
            return is;
        }
        dv.timeChanged = date + " " + time;
        dv.value = value;
    }
    return is;
}

次に、次のように簡単にベクトルを埋めることができます。

std::ifstream fin("myData.txt");
std::istream_iterator<DataValue> beg(fin), end;
std::vector<DataValue> v(beg,end);
于 2012-06-26T06:00:01.880 に答える
0

push_back明らかに、stlベクトルだけで可能です。ただし、それを実行している場合は、ベクトルの長さを知ってください。このreserve関数を使用して、ベクトルのサイズを変更する必要がないように、十分なスペースを格納するように要求することもできます。

または、関数呼び出しを使用して、resizeすでに必要なサイズのstlベクトルを入力することもできます。

http://www.cplusplus.com/reference/stl/vector/

ifstreamのgetline関数からデータを取得することもできます

http://www.cplusplus.com/reference/iostream/istream/getline/

于 2012-06-26T05:38:07.757 に答える