0

文字列のコレクションをオブジェクトの配列に含むテキスト ファイルを読み込もうとしていますが、入力に問題があります。istream here に移動するエラーが表示されます

*_Str = _Elem();    // add terminating null character

C++ で文字列を使用する方法についてはよくわからないので、助けていただければ幸いです。

私のコード:

char bird_name[MAX_LINE_LENGTH];
char* description =new char [MAX_LINE_LENGTH];
char* sound=new char [MAX_LINE_LENGTH];
int num_states= 0;
char* states[10];
bool valid = true;
char* state_name = new char [MAX_LINE_LENGTH];

for (int j =0; j<10; j++)
states[j]=new char [MAX_LINE_LENGTH];

char *input_filename = argv[1];

ifstream input(input_filename);
if (!input.is_open())
{
cerr << "Invalid filename: " << input_filename << endl;
system("pause");
return 1;
}



input.getline(bird_name, MAX_LINE_LENGTH);

char* state_num = new char [MAX_LINE_LENGTH];
while (strcmp(bird_name, "END") != 0) 
{
    input.getline(description, MAX_LINE_LENGTH);
    consume_newline(input);
    input.getline(sound, MAX_LINE_LENGTH);
    consume_newline(input);
    input.getline(state_num, MAX_LINE_LENGTH);
    num_states = int(state_num);
    consume_newline(input);
    for (int k = 0; k<num_states; k++)

        input.getline(states[k], MAX_LINE_LENGTH);

    consume_newline(input);
    consume_newline(input);

    birds[num_birds++] = new Bird(bird_name, description, sound, num_states, states);

    //birds[num_birds]->display();
    input.getline(bird_name, MAX_LINE_LENGTH);
}
4

1 に答える 1

1

あなたが言及した問題のあるコードは…

    *_Str = _Elem();    // add terminating null character

おそらく、標準ライブラリのソースコードファイルからのものです。

独自のコードでは、アンダースコアで始まり大文字が続く識別子を使用しないでください。これらは実装用に予約されているためです (上記のコードなど)。

このコメントは、標準の lib コードが入力の完全な行をバッファーに読み込み、終端のヌルバイトを追加しようとすると、事態がうまくいかないことを示しています。

これは、バッファが小さすぎるか、標準ライブラリ コードに渡されたバッファ ポインタが有効ではないことを示しています。

あなたが示しているコードでそれを見つけることができません。そして、あなたが示しているコードは、問題が現れるコードではないと思います将来のために注意してください: 可能であれば、1 ミリ秒前にテストした完全なコードを投稿してください…

とにかく、問題を修正するために、どこで何が問題になっているのかを (詳細に) 正確に知る必要はありません。「アレクサンドリアのソリューション」を採用するだけです。この表現は、アレキサンダー大王が、本当に悪い結び目をほどくためのロープの端を見つけることができなかったときに、剣でそれを真っ二つに切り裂いたことを指しています。

だからあなたの宣言を考えてください…

char* description =new char [MAX_LINE_LENGTH];

さて、私たちの顔を睨みつけている最初の明らかな間違いは、すべて大文字の識別子の使用です。マクロ用に予約してください。すると…

char* description =new char [max_line_length];

第 2 に、生のポインターと rawを使用することnewは、一般的に単に悪い™ です。だからそれを取り除きます。次に、次のように見えます…

char description[max_line_length];

第 3 に、そのような生の配列を使用することは多くの場合良い解決策ですが、これは可変長の文字列に使用されていることがわかります。そして、その使用法では、それはただのBad™です. 代わりに、標準ライブラリの などの文字列クラスのオブジェクトを使用しますstd::string

std::string description;

そのためには [string] ヘッダーを含める必要があります#include <string>

第 4 に、この変数はループ内でのみ使用されるため、宣言をループ内に移動してください。

第 5 に、現在、呼び出しstd::stringを変更する必要があります...getline

input.getline(description, MAX_LINE_LENGTH);

[string] ヘッダーから独立したgetline関数を使用するには、つまり…

std::getline( input, description );

第 6 に、入力操作のエラー チェックがありません。エラー チェックとエラー処理を追加する必要があります。inputとしてそれを仮定すると、std::istreamチェックできinput.fail()ます。true入力操作が失敗した場合です。

Sevent…ああ、論理的にはここに 7 番目のポイントがあるはずです。なぜなら、7 は 6 よりもはるかに好ましい数だからです。ただし、この 7 番目のポイントに当てはまることは何もありません。

乾杯 & hth.,

于 2011-10-22T03:09:24.033 に答える