0

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

提供的函数正在读取一个看起来像这样的文件。

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 次。我已经修改了我(人类)认为我应该如何修改文件。我过去遇到过问题,就是这样做的。(仍在处理程序的其他部分,所以我现在不能太具体,但我知道我的结果出乎意料)所以我的问题是我修改的功能是否适合我想要做的事情?我差一个吗?我想我正在努力理解原始功能是如何工作的。(逐步系统地。)因此我对修改后的功能感到困惑。

我还可以提供您想查看的任何其他功能,我的 setter 和 getter。此外,如果您有任何问题或反馈,我将不胜感激。

4

1 回答 1

1

原始函数和修改后的函数都是错误的:在尝试阅读某些内容后,您总是需要检查输入是否成功(我想,如果我最终去世,我的墓碑上会刻上那个……)。用于控制输入循环通常不起作用in.eof()

如果该行以少于MAX_CHAR字符的字符串结尾,则忽略下一行:您需要检查输入是否以换行符结尾,如果不是,则忽略剩余的字符。如果最后一个输入以换行符结尾,您不想忽略字符。此外,如果该行恰好以超过 100 个字符的字符串结尾,它也不起作用。std::istream::ignore()忽略尽可能多的字符的神奇常数是拼写不方便的,std::numeric_limits<std::streamsize>::max()并在标题<limits>中声明。

基本上,你的循环应该从

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
}

代码使用std::istream::getline()前两个组件来避免存储分隔符:提取分隔符并停止输入就足够了。使用最后一个组件std::istream::get()是因为有必要验证存储的最后一个字符是否为换行符。存储的最后一个字符是 access using std::istream::gcount(),它包含最后一个未格式化的输入函数存储的字符数。由于输入成功并且它会在存储换行符或存储MAX_CHAR字符后停止,in.gcount() - 1因此始终是有效索引。但是请注意,代码未经测试...

于 2013-11-09T20:18:02.813 回答