0

ファイルを入力し、各単語を次のように個別の char* として読み取るコードを書いています。

char label[8];
char type[5];
char value[6];


while (!input.eof()) {
    input >> label;
    input >> type;
    input >> value;
    storeSymbols(label, type, value);
}

次に、次のように char* 配列の要素に設定します。

void storeSymbols(char* lab, char* type, char* val) {
    labels[symCount] = lab;
    types[symCount] = type;
    values[symCount] = val;
    symCount++;

}

ただし、char* 配列のすべての要素を出力すると、すべての要素がファイルから取得した最後の要素と同じになります。たとえば、ドキュメントに 3 つのラベルがあり、「1」、「2」、「3」と定義されている場合、最初のループの最後では配列に「1」が含まれ、2 回目では「」が含まれます。 two」と「two」、3回目は「three」「three」と「three」が含まれます。また、余分な時間をループして、最後の要素をもう一度配列に追加し、配列内の 4 つの "3" 要素にします。なぜこれが起こっているのか誰にも分かりますか?

値を int に変換して int 配列に追加したところ、これもテストしましたが、正常に動作します。

4

2 に答える 2

0

入力を読み取っているループは、各アイテムを以前に使用されたのと同じバッファーに格納しているだけです。たとえば、input >> label読み取ったアイテムをchar label[8]毎回同じバッファに保存します。したがって、いつでも、そのlabel配列には最後に読み取られたアイテムのみが含まれます。

次に、その情報を保存しようとすると、配列のアドレス(毎回同じアドレスstoreSymbols())を渡します。labelしたがって、配列の各要素labels(私はの配列であると想定していchar*ます)は同じポインターを取得します-それらはそれぞれ、更新される同じバッファーを指します。

個別のアイテムへのポインタを格納できるようにする簡単な変更はstrdup()、文字列を複製するために使用することです。割り当てでの使用が許可されていない場合はstrdup()、同等の機能を10行未満のコードで関数として記述できます。

を使用するstrdup()と、ポインタを格納していない文字列が動的に割り当てられるため、使用が終了したら、文字列を解放する必要があります。

for (i = 0; i < symCount; ++i) {
    free(labels[i]);
    free(types[i]);
    free(values[i]);
}

最後の項目が入力から読み取られた後の余分な時間のループについての質問では、入力の読み取りに使用するループは、EOF直接チェックするアンチパターンを使用します。EOF入力ストリームが「空」のときに実際に読み取りを実行しようとするまで、は設定されません。「while(!feof(file))」が常に間違っているのはなぜですか?を参照してください。およびhttp://drpaulcarter.com/cs/common-c-errors.php#4.2

試す:

while (input >> label >> type >> value) {
    storeSymbols(label, type, value);
}

また、入力バッファがデータに対して十分な大きさであることを確認してください(ヌルターミネータに注意してください)。std::string理想的には、入力を読み取るときに動的に拡張する(のような)データ型を使用します。

于 2013-03-11T14:12:51.020 に答える
0

明らかにCではなくC++を使用しているため、ラベルを格納するために代わりに使用し、ラベルなどを格納するために配列のstd::string代わりに使用します。char *vector

したがって:

std::vector<std::string> labels, types, values;

std::string label, type, value;
input >> label >> type >> value;

labels.push_back(label);
types.push_back(type);
values.push_back(value);

同じ出力が繰り返し表示される理由は、ポインターを同じ固定グローバル配列にプッシュしているためです。この配列は、によって繰り返し上書きされinput >> labelます。std::string内部バッファをコピーして割り当てることにより、これを回避します(すべて自動的に行われます)。

于 2013-03-11T02:09:40.300 に答える