добавить нулевой терминатор при ошибке istream - PullRequest
0 голосов
/ 22 октября 2011

Я пытаюсь прочитать текстовый файл, содержащий наборы строк, в массив объектов, и у меня возникли проблемы с вводом. Я получаю ошибку, которая идет в istream здесь

*_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);
}

1 Ответ

1 голос
/ 22 октября 2011

упомянутый вами код обидчика, & hellip;

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

предположительно из некоторого стандартного файла исходного кода библиотеки.

Обратите внимание, что в вашем собственном коде вы не должны использовать идентификаторы, начинающиеся с символа подчеркивания, за которым следует верхний регистр, поскольку они зарезервированы для реализации (например, кода выше).

Комментарий указывает, что дела идут плохо, когда стандартный код lib прочитал полную строку ввода в буфер и пытается добавить завершающий нулевой байт.

Это, в свою очередь, указывает на то, что буфер слишком мал или указатель буфера, переданный в стандартный код библиотеки, недействителен.

Я не могу найти это в коде, который вы показываете. И я подозреваю , что код, который вы показываете, не тот код, в котором проявляется проблема. Обратите внимание, что на будущее: если это вообще возможно, опубликуйте полный код, который вы тестировали одну миллисекунду назад & hellip;

В любом случае, нет необходимости точно знать, где и что идет не так (подробно), чтобы исправить ситуацию. Вы можете просто использовать & ldquo; александрийское решение & rdquo ;. Это выражение относится к Александру Великому, который, когда он не мог найти какой-либо конец веревки, чтобы начать разворачивать действительно Плохой узел & trade;, просто разрезал его пополам своим мечом.

Так что рассмотрите ваше заявление & hellip;

char* description =new char [MAX_LINE_LENGTH];

Теперь первая очевидная вещь, которая не в порядке с этим, бросая нам в глаза, это использование идентификатора ALL UPPERCASE . Зарезервируйте это для макросов. Тогда это становится & hellip;

char* description =new char [max_line_length];

Во-вторых, при использовании необработанного указателя и необработанного new, обычно это просто Bad & trade ;. Так что избавься от этого. Тогда это выглядит как & hellip;

char description[max_line_length];

В-третьих, использование необработанного массива , подобного этому, часто является хорошим решением, но оказывается, что этот используется для строки переменной длины. И для этого использования, это просто Bad & trade ;. Вместо этого используйте объект некоторого строкового класса, такого как стандартная библиотека & rsquo; s std::string:

std::string description;

Для этого вам необходимо включить заголовок [string], т.е. #include <string>.

В-четвертых, эта переменная используется только внутри цикла , поэтому переместите объявление внутри цикла!

Пятое, с std::string вам нужно изменить getline вызов, в настоящее время & hellip;

input.getline(description, MAX_LINE_LENGTH);

для использования автономной функции getline из заголовка [string], а именно & hellip;

std::getline( input, description );

В-шестых, нет ошибок при операциях ввода. Вам необходимо добавить проверку ошибок и обработку ошибок. Предполагая, что input как std::istream, тогда вы можете проверить input.fail(); это - true, если какая-то операция ввода не удалась.

Sevent & hellip; О, здесь логически должно быть седьмое, потому что число семь гораздо приятнее, чем шесть. Однако мне нечего сказать, что вписывается в седьмой пункт.

Приветствия и hth.,

...