在istream错误上添加Null终结符

时间:2011-10-22 01:54:24

标签: c++ istream

我正在尝试将包含字符串集合的文本文件读入对象数组,并且输入有问题。我得到一个错误,这里有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 个答案:

答案 0 :(得分:1)

你提到的违规代码,......

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

可能来自某些标准库源代码文件。

请注意,在您自己的代码中,您不应该使用以下划线开头,后跟大写的标识符,因为它们是为实现保留的(例如上面的代码)。

注释表明,当标准的lib代码已经读入缓冲区的完整输入行并尝试添加终止空字节时,事情就会出错。

反过来表明缓冲区太小,或者缓冲区指针传递给标准库代码,甚至都没有效。

我无法在您显示的代码中找到它。并且我怀疑您显示的代码不是问题所显示的代码。请注意,对于未来:如果可能的话,发布您在一毫秒前测试过的完整代码......

无论如何,为了解决问题,没有必要确切地知道在哪里和出了什么问题(详细)。你可以使用“亚历山大解决方案”。那个表达指的是亚历山大大帝,当他找不到任何绳索开始解开一个真正的Bad Knot™时,只用剑将它切成两半。

请考虑您的声明......

char* description =new char [MAX_LINE_LENGTH];

现在第一个明显的错误就是使用了 ALL UPPERCASE 标识符。为宏保留。然后就变成......

char* description =new char [max_line_length];

其次,使用原始指针和原始new通常只是Bad™。所以摆脱它。然后它看起来像......

char description[max_line_length];

第三,使用像这样的原始数组通常是一个很好的解决方案,但事实证明这个用于变长字符串。对于这种用法,它只是Bad™。而是使用某个字符串类的对象,例如标准库的std::string

std::string description;

您需要包含[string]标题,即#include <string>

第四,这个变量只在循环中使用 ,所以在循环中移动声明!

第五,使用std::string,您需要更改getline来电,目前...

<德尔> input.getline(description, MAX_LINE_LENGTH);

使用[string]标题中的独立getline函数,即......

std::getline( input, description );

第六,输入操作没有错误检查。您需要添加错误检查和错误处理。假设inputstd::istream,那么您可以检查input.fail();如果某些输入操作失败,则为true

Sevent ......哦,从逻辑上讲,这里应该是第七点,因为七是一个比六个更令人满意的数字。但是,我没有什么可说的,这符合第七点。

干杯&amp;第h。,