免责声明这是针对家庭作业的问题。不要求提供我正在编写的程序的完整解决方案,而只是要求更好地了解正在发生的事情。提前致谢。

提供的功能正在从一个看起来像这样的文件中读取。

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始终是有效索引。但是请注意,该代码未经过测试...

07-24 19:25
查看更多