2010-12-10 61 views
1

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

一)从回路断线

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

所以删除它,你更喜欢哪解决,为什么?初学者最容易理解哪一个?

回答

2

我更喜欢(a)。简单而且很自然地阅读。 (b)重复获取输入的行。 (c)和(d)都使用可能会让初学者感到困惑的语法(具体来说,逗号不在for语句或定义中,并且在条件中赋值)。尽管如此,我可能更喜欢(c)而不是(d)。 (e)效率不高。如果最后的push_back导致重新分配,该怎么办?

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

+0

这样的方式,矫枉过正他是什么试图完成。 – 2010-12-10 14:21:33

+0

我想这取决于你需要这么做的频率 - 如果你只使用它一次,我可以看到你可以争辩说它有点矫枉过正,但鉴于它只有大约10行代码,我不要以为你必须经常用它来证明它的合理性。 – 2010-12-10 14:25:05

2

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

- 它显示在我认为最好的是什么做:首先读取数据,那么如果它不是“好”的数据(空行)停止阅读数据。并且一切都处于预期的位置(检查数据是否处于循环条件部分,处理循环体中的数据)

Mtheod“a”隐藏条件检查&这是比较困难的),看看哪些“停止”的循环中的条件。

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