免责声明这是针对家庭作业的问题。不要求提供我正在编写的程序的完整解决方案,而只是要求更好地了解正在发生的事情。提前致谢。
提供的功能正在从一个看起来像这样的文件中读取。
foo;bar
foo;bar
我想修改该功能以从看起来像这样的文件中读取
foo;bar;foobar
foo;bar;foobar
提供的功能看起来像
void EntryList::loadfile(const char filefoo[])
{
ifstream in;
char foo[MAX_CHAR];
char bar[MAX_CHAR];
AddressEntry anEntry;
in.open (filefoo);
if(!in)
{
in.clear();
cerr << endl << "Fail to open " << filefoo << " for input!" << endl << endl;
exit(1);
}
in.get(foo, MAX_CHAR, ';');
while (!in.eof())
{
in.get(); //remove field seperator ';'
in.get(bar, MAX_CHAR, '\n');
in.ignore(100, '\n'); //remove record seperator '\n'
anEntry.setfoo(foo);
anEntry.setbar(bar);
addEntry(anEntry);
in.get(foo, MAX_CHAR, ';'); //start the next record
}
in.close();
}
我修改的功能看起来像
void EntryList::loadfile(const char fileName[])
{
ifstream in;
char foo[MAX_CHAR];
char bar[MAX_CHAR];
char foobar[MAX_CHAR];
TaskList theEntry;
in.open(fileName);
if (!in) {
in.clear();
cerr << endl
<< "Failed to open "
<< fileName
<< " for input!" << endl << endl;
exit(1);
}
in.get(foo, MAX_CHAR, ';');
while (!in.eof())
{
in.get(); // rm ;
in.get(bar, MAX_CHAR, ';');
in.get(foobar, MAX_CHAR, '\n'); // rm '\n'
in.ignore(100, '\n');
theEntry.setfoo(foo);
theEntry.setbar(bar);
theEntry.setfoobar(foobar);
addEntry(theEntry);
in.get(foo, MAX_CHAR, ';');
}
in.close();
}
我至少要重写该程序4次。
我已经修改了该文件,以我(人类)认为应该的方式
为此。我过去曾经遇到过这样的问题。 (仍在程序的其他部分上工作,因此我现在不能太过具体,但我知道我的结果出乎意料了。)所以我的问题是,我修改的函数对我正在尝试执行的功能是否正确?我一个人走吗?我想我在努力理解原始功能是如何工作的。 (系统地逐步进行。)因此,我对修改后的功能感到困惑。
我还可以提供您想要查看的其他功能,即我的设置者和获取者。另外,如果您有任何疑问或反馈,我们将不胜感激。
最佳答案
原始功能和修改后的功能都是错误的:在尝试读取某些内容后,您始终需要检查输入是否成功(我想,如果我最终逝世,我的墓碑上将刻有该符号……)。使用in.eof()
控制输入循环通常是行不通的!
如果该行以少于MAX_CHAR
个字符的字符串结尾,那么下一行将被忽略:您需要检查输入是否以换行符结尾,否则请忽略其余字符。如果最后一个输入以换行符结尾,则您不想忽略字符。另外,如果该行恰好以超过100个字符的字符串结尾,则它也不起作用。不方便地将std::istream::ignore()
忽略尽可能多的字符的魔术常数拼写为std::numeric_limits<std::streamsize>::max()
,并在标头>中声明。
基本上,您的循环应以
while (in.getline(foo, MAX_CHAR, ';')
.getline(bar, MAX_CHAR, ';')
.get(foobar, MAX_CHAR, '\n')) {
if (foobar[in.gcount() - 1] == '\n') {
foobar[in.gcount() - 1] = '\0';
}
else {
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// process the inputs
}
该代码对前两个组件使用
<limits
以避免存储分隔符:提取分隔符并停止输入就足够了。对于最后一个组件,使用std::istream::getline()
是因为有必要验证存储的最后一个字符是否为换行符。使用std::istream::get()
访问存储的最后一个字符,该字符包含最后一个未格式化的输入函数存储的字符数。由于输入成功,并且在存储换行符或存储std::istream::gcount()
字符后它将停止,因此MAX_CHAR
始终是有效索引。但是请注意,该代码未经过测试...