在 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);
}
I am trying to read a text file that has collections of strings into an array of objects, and am having problems with the input. I get an error that goes to istream here
*_Str = _Elem(); // add terminating null character
I don't really know much about how to use strings in C++, so any help would be appreciated.
my code:
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您提到的有问题的代码……
可能来自某些标准库源代码文件。
请注意,在您自己的代码中,不应使用以下划线后跟大写字母开头的标识符,因为它们是为实现保留的(例如上面的代码)。
该注释表明,当标准库代码将完整的输入行读入缓冲区并尝试添加终止空字节时,事情就会出错。
这反过来表明缓冲区太小,或者传递给标准库代码的缓冲区指针甚至无效。
我无法在您显示的代码中找到它。我怀疑您所显示的代码不是出现问题的代码。请注意,对于未来:如果可能的话,发布您在一毫秒前测试过的完整代码……
无论如何,没有必要准确地知道哪里出了问题以及出了什么问题(详细)来修复问题。您可以采用“亚历山大解决方案”。这个表达指的是亚历山大大帝,当他找不到任何绳头来开始解开一个真正的坏结™时,他只是用剑将其切成两半。
所以考虑一下你的声明……
现在第一个明显的错误是使用了全部大写标识符,这让我们眼前一亮。为宏保留它。然后它就变成了……
其次,使用原始指针和原始
new
通常只是Bad™。所以摆脱它吧。然后它看起来像……第三,使用像这样的原始数组通常是一个很好的解决方案,但事实证明这个数组用于可变长度字符串。对于这种用法,它只是 Bad™。相反,使用某个字符串类的对象,例如标准库的
std::string
:您需要为此包含 [string] 标头,即
#include
代码>.第四,该变量仅在循环内使用,因此将声明移至循环内!
第五,使用
std::string
,需要更改getline
调用,目前...input.getline(description, MAX_LINE_LENGTH);
使用 [string] 标头中独立的
getline
函数,即……第六,对输入操作没有错误检查。您需要添加错误检查和错误处理。假设
input
作为std::istream
,那么您可以检查input.fail()
;如果某些输入操作失败,则为true
。七……哦,从逻辑上讲,这里应该是第七点,因为七是一个比六更令人愉快的数字。然而,对于第七点,我没有什么可说的。
干杯&呵呵,
The offending code you mention, …
is presumably from some standard library source code file.
Note that in your own code you should not use identifiers starting with underscore followed by uppercase, since they are reserved for the implementation (such as the code above).
The comment indicates that things go awry when the standard lib code has read a complete line of input into the buffer, and is trying to add a terminating null-byte.
That in turn indicates that the buffer is too small, or that the buffer pointer handed to the standard library code, is not even valid.
I am unable to find that in the code that you’re showing. And I suspect that the code you’re showing is not the code where the problem manifests. Please note that for the future: if at all possible, post complete code that you have tested one millisecond ago…
Anyway, it’s not necessary to know exactly where and what goes wrong (in detail) in order to fix things. You can just employ an “Alexandrian solution”. That expression refers to Alexander the Great who, when he could not find any rope end to start untying a really Bad Knot™, just sliced it in two with his sword.
So consider your declaration …
Now the first obvious thing that is wrong with that, glaring us in the face, is the use of an ALL UPPERCASE identifier. Reserve that for macros. Then it becomes …
Second, using a raw pointer, and raw
new
, is generally just Bad™. So get rid of that. Then it looks like …Third, using a raw array like that is often a good solution, but it turns out that this one is being used for a variable length string. And for that usage, it is just Bad™. Instead use an object of some string class, such as the standard library’s
std::string
:You need to include the [string] header for that, i.e.
#include <string>
.Fourth, this variable is only used inside the loop, so move the declaration inside the loop!
Fifth, with
std::string
, you need to change thegetline
call, currently …input.getline(description, MAX_LINE_LENGTH);
to use the freestanding
getline
function from the [string] header, namely …Sixth, there is no error checking on input operations. You need to add error checking and error handling. Assuming that
input
as astd::istream
, then you can checkinput.fail()
; it’strue
if some input operation has failed.Sevent… Oh there should logically be seventh point here, since seven is a much more pleasing number than six. However, I have nothing to say that will fit into this seventh point.
Cheers & hth.,