阅读直到用户输入空行

发布于 2024-10-06 21:14:48 字数 1103 浏览 0 评论 0原文

假设我想从控制台读取行并将其放入容器中,直到用户输入空行。不过,我不希望该空行出现在我的容器中。我可以想到五种不同的解决方案:

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();

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

Suppose I want to read lines from the console and put those into a container until the user enters a blank line. I do not want that blank line ending up in my container, though. I can think of five different solutions:

a) break from loop

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

b) read before loop and inside loop

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

c) read as part of loop condition, assignment version

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

d) read as part of loop condition, sequence version

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

e) read too much, remove it after loop

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

So, which solution would you prefer, and why? Which would be the easiest to understand for a beginner?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

鲜肉鲜肉永远不皱 2024-10-13 21:14:48

我更喜欢(a)。简单,读起来很自然。

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

(c) 和 (d) 都使用了可能会让初学者感到困惑的语法(特别是 for 语句或定义中没有逗号,以及条件语句中的赋值)。不过,我可能更喜欢(c)而不是(d)。

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

I prefer (a). simple and reads quite naturally.

(b) repeats the line that gets the input.

(c) and (d) both use syntax that may be confusing to beginners (specifically, the comma not within a for statement or a definition, and assignment within a conditional). I'd probably prefer (c) over (d) though.

(e) is... inefficient. What if that last push_back caused a reallocation?

白云悠悠 2024-10-13 21:14:48

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

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

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

I'd use method "d" actually:

-It shows in my opinion best what is done: first read the data, then if it isn't "good" data (empty line) stop reading the data. And everything is at the expected position (checking the data is in the loop-condition part, handling the data in the loop-body.

Mtheod "a" hides the condition checking & it is more difficult (in my humble opinion) to see the condition which "stops" the loop.

清风疏影 2024-10-13 21:14:48

正如您可能对我所期望的那样,我建议使用代理:

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 来读取输入,并且它将在转换失败时停止。

As you'd probably expect from me, I'd suggest a proxy:

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);

This has a side-effect that might be unexpected though: since it expects to read non-blank lines, it considers a blank line a failed conversion -- which means to read more from the stream afterwards, you have to clear the stream's fail bit. Since it does work by setting the stream's fail bit, you should also be able to use std::copy to read the input and it'll stop at the failed conversion.

寄居者 2024-10-13 21:14:48

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

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

A modification to (d) makes it more efficient and follows what you are trying to do better.

std::vector<std::string> container;
std::string line;
do
{
    line = get_input();
    if (!line.empty())
    {
        container.push_back(line);
    }
    else
    {
        break;
    }
}
while (true);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文