【问题标题】:Infinite loop with file handling and istringstreams带有文件处理和 istringstreams 的无限循环
【发布时间】:2013-11-19 10:37:10
【问题描述】:

我有一个包含以下格式数据的文件:

ballcolor 10
bgcolor 5
[...]

我正在尝试通过以下方式阅读:

void read (const char *filename)
{
    ifstream prefsfile (filename);
    if (prefsfile.is_open ())
    {
        char prefsline [BUFSIZE], prefname [BUFSIZE];
        unsigned int value;

        while (! prefsfile.eof ())
        {
            prefsfile.getline (prefsline, BUFSIZE);

            istringstream iss (prefsline);
            iss >> prefname >> value;
            if (! (iss.fail () || prefsfile.fail ()))
            {
                if (! strcmpi (prefname, PREFSTR_PAD_COLOR) && value <= BACKGROUND_MAX)
                {
                    color.pad = value << 4;
                }
                else if (! strcmpi (prefname, PREFSTR_BALL_COLOR) && value <= FOREGROUND_MAX)
                {
                    color.ball = value;
                }
                else if (! strcmpi (prefname, PREFSTR_FOREGROUND_COLOR) && value <= FOREGROUND_MAX)
                {
                    color.foreground = value;
                }
                else if (! strcmpi (prefname, PREFSTR_BACKGROUND_COLOR) && value <= BACKGROUND_MAX)
                {
                    color.background = value << 4;
                    color.ball |= color.background;
                }
            }
        }
        prefsfile.close ();
    }
}

如果我给它一个完全符合上面显示的格式的文件,它就会很好地工作。但是,如果文件不符合要求,或者每行的长度大于BUFSIZE(=30),则会进入无限循环。

我该如何解决这个问题?

【问题讨论】:

  • 如果 prefsline 的长度为 BUFSIZE,则您的 getline 语句应为 prefsfile.getline (prefsline, BUFSIZE); 否则您可能会超出缓冲区的末尾。
  • @TomFenech,正如我上面所说的BUFSIZE 是 30;无论如何编辑以更正它。
  • while (! prefsfile.eof ()) 是错误的。谁教你这样做的?

标签: c++ fstream istringstream


【解决方案1】:

您正在检查! prefsfile.eof (),但如果您检查更通用的prefsfile.good(),如果行长于BUFSIZE,您的循环应该会中断。

The getline reference 解释了何时设置了故障位。特别是,如果在从输入中读取 BUFSIZE 字符时仍未找到分隔符。

我会这样读取文件:

void read (const char *filename)
{
    ifstream prefsfile (filename);
    if (prefsfile.is_open ())
    {
        char prefsline [BUFSIZE], prefname [BUFSIZE];
        unsigned int value;

        while (prefsfile.getline(prefsline, BUFSIZE))
        {                        
            if (prefsfile.eof()) {
                break;
            }

            istringstream iss (prefsline);
            iss >> prefname >> value;
            cout << prefname << " " << value << "\n";
        }
        prefsfile.close ();
    }
}

如果行太长,while 循环条件将评估为 false。

测试 1 - 长行打破循环

ballcolor 10
really really long line that is over 30 characters
bgcolor 5

输出:

ballcolor 10

测试 2 - 较短的行

ballcolor 10
bgcolor 5

输出:

ballcolor 10
bgcolor 5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多