0

我正在尝试将包含字符串集合的文本文件读取到对象数组中,并且输入有问题。我收到一个错误,该错误在此处转到 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);
}
4

1 回答 1

1

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

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

大概来自一些标准库源代码文件。

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

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

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

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

无论如何,为了解决问题,没有必要(详细)确切地知道哪里和哪里出了问题。您可以使用“亚历山大解决方案”。那句话指的是亚历山大大帝,当他找不到任何绳头开始解开一个真正的坏结™时,就用他的剑将它切成两半。

所以考虑你的声明……

char* description =new char [MAX_LINE_LENGTH];

现在第一个明显的错误是使用全大写标识符,让我们眼前一亮。为宏保留它。然后就变成了……

char* description =new char [max_line_length];

其次,使用原始指针和 rawnew通常只是 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 );

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

Sevent……哦,这里应该有第七点,因为七是一个比六更令人愉悦的数字。但是,我没有什么要说的适合这第七点。

干杯&hth.,

于 2011-10-22T03:09:24.033 回答