阅读,直到用户输入空行

时间:2010-12-10 13:53:01

标签: c++ string loops containers user-input

假设我想从控制台读取行并将它们放入容器中,直到用户输入空行。不过,我不希望那个空白行在我的容器中结束。我可以想到五种不同的解决方案:

a)从循环中断

std::vector<std::string> container;
for (; ;)
{
    std::string line = get_input();
    if (line.empty()) break;
    container.push_back(line);
}

b)在循环和内循环之前读取

std::vector<std::string> container;
std::string line = get_input();
while (!line.empty())
{
    container.push_back(line);
    line = get_input();
}

c)作为循环条件的一部分读取,赋值版本

std::vector<std::string> container;
std::string line;
while (!(line = get_input()).empty())
{
    container.push_back(line);
}

d)作为循环条件的一部分读取,序列版本

std::vector<std::string> container;
std::string line;
while (line = get_input(), !line.empty())
{
    container.push_back(line);
}

e)读取太多,在循环后删除它

std::vector<std::string> container;
std::string line;
do
{
    line = get_input();
    container.push_back(line);
}
while (!line.empty());
container.pop_back();

那么,您更喜欢哪种解决方案?为什么?哪个对于初学者来说最容易理解?

4 个答案:

答案 0 :(得分:2)

我更喜欢(a)。简单而且阅读很自然。

(b)重复获得输入的行。

(c)和(d)都使用可能使初学者感到困惑的语法(具体来说,逗号不在for语句或定义中,并且在条件内分配)。我可能更喜欢(c)而不是(d)。

(e)......效率低下。如果最后push_back导致重新分配怎么办?

答案 1 :(得分:2)

我实际上使用方法“d”:

- 在我看来最好的做法是:首先读取数据,然后如果不是“好”数据(空行)停止读取数据。一切都在预期的位置(检查数据是在循环条件部分,处理循环体中的数据。

Mtheod“a”隐藏了条件检查&amp; (以我的拙见)更难以看到“停止”循环的条件。

答案 2 :(得分:0)

正如你可能对我的期望,我建议代理:

class non_blank {
   std::string data;

   friend operator>>(std::istream &is, non_blank &n) {
       std::string temp;

       std::getline(is, temp);

       // I'm not writing this from home, so I'm going from memory.
       // The following line is probably a little wrong.
       is.setbit(std::ios::fail, temp.length()!=0);
       return is;
   }
   operator std::string() { return data; }
};

non_blank line;
while (infile >> line)
    container.push_back(line);

这有一个可能出乎意料的副作用:因为它希望读取非空白行,它认为空行是转换失败 - 这意味着之后从流中读取更多内容,你必须清除流的失败位。由于它通过设置流的失败位而起作用,因此您还应该能够使用std::copy来读取输入,并且它将在转换失败时停止。

答案 3 :(得分:0)

对(d)的修改使其更有效率并遵循您想要做得更好的事情。

std::vector<std::string> container;
std::string line;
do
{
    line = get_input();
    if (!line.empty())
    {
        container.push_back(line);
    }
    else
    {
        break;
    }
}
while (true);