0

我正在尝试在我的程序中编写一个函数,该函数加载一个包含 216,555 个单词的巨大文本文件并将它们作为字符串放入一个集合中。这可以正常工作,但正如预期的那样,它会在循环文件时挂起几微秒。但是我的循环发生了一些奇怪的事情,而且它的行为不正常。请花时间阅读,我确信这是有正当理由的,但我不知道要搜索什么。

顺便说一句,代码是这样的:

ifstream dictionary;
dictionary.open("Dictionary.txt");

if(dictionary.fail())
{
    cout<<"Could not find Dictionary.txt. Exiting."<<endl;
    exit(0);
}
int i = 0;
int progress = 216555/50;
cout<<"Loading dictionary..."<<endl;
cout<<"<                                                  >"<<endl;
cout<<"<";
for(string line; getline(dictionary, line);)
{
    usleep(1); //Explanation below (not the hangtime)
    i++;
    if(i%progress == 0)
        cout<<"=";
    words.insert(line);
}

for 循环从文件中获取每个字符串,并将它们插入到映射中。这是一个控制台应用程序,我希望用户看到进度。这不是什么延迟,但我还是想这样做。如果您不理解代码,我将尝试解释。

当程序启动时,它首先打印出“Loading Dictionary...”,然后是由 50 个空格分隔的“<”和“>”。然后在下一行:“<”后跟一个“=”,表示它循环通过的每 433 个单词 (216555/50)。这样做的目的是让用户可以看到进度。循环中途所需的输出将如下所示:

Loading dictionary...
<                                                  >
<=========================                         

我的问题是: 显示了正确的输出,但不是在预期的时间。它打印出完整的进度条,但只有在它挂起并完成循环之后。这怎么可能?显示了正确数量的“=”,但它们都同时弹出,在它挂起几微秒之后。我添加了 usleep(1) 以延长挂起时间,但同样的事情发生了。if 语句显然有效,或者“=”根本不会显示,但感觉就像我的程序在整个循环之后堆叠 cout 调用。

最奇怪的是,cout<<"<";for循环开始之前的最后一个,也与它的行的其余部分同时显示;循环结束后。为什么以及如何?

4

3 回答 3

3

您永远不会刷新流,因此输出只会进入缓冲区。

更改cout<<"=";cout<<"="<<std::flush;

于 2013-04-23T04:10:24.293 回答
3

您需要刷新输出流。

cout << "=" << std::flush;
于 2013-04-23T04:10:24.973 回答
1

该程序“堆叠 cout-calls”。它被称为输出缓冲,每个主要操作系统都这样做。

当处于交互模式时(因为您的程序打算被使用),输出按行缓冲;也就是说,当看到换行符时,它将被强制到终端。您还可以有块缓冲(强制输出之间的固定字节数;在管道输出时使用)和无缓冲。

C++ 提供了std::flush流修饰符来在任何时候强制输出。它可以这样使用:

cout << "=" << std::flush;

这会使您的程序变慢一点;缓冲的目的是为了提高效率。但是,由于您只会执行大约 51 次,因此减速应该可以忽略不计。

于 2013-04-23T04:14:54.923 回答