0

在阅读了关于 C/C++ 中逗号运算符的一个很好的答案后(逗号运算符是做什么的- 我使用相同的示例代码),我想知道哪种是实现 while 循环的最易读、可维护、首选的方法。特别是一个while循环,其条件取决于操作或计算,并且第一次条件可能为假(如果循环总是至少通过一次,那么do-while就可以正常工作)。

逗号版本是最喜欢的吗?(每个答案怎么样,其余的可以通过相应的投票来投票?)

简单的实现

此代码具有重复的语句,(很可能)必须始终相同。

string s;
read_string(s);     // first call to set up the condition
while(s.len() > 5)  // might be false the first pass
{
   //do something
   read_string(s);  // subsequent identical code to update the condition
}

使用break实现

string s;
while(1)                  // this looks like trouble
{
   read_string(s);
   if(s.len() > 5) break; // hmmm, where else might this loop exit
   //do something
}

使用逗号实现

string s;
while( read_string(s), s.len() > 5 ) 
{
   //do something
}
4

2 回答 2

3

我会说以上都不是。我看到了几个选项。它们之间的选择取决于您的实际限制。

一种可能性是你有一个应该总是有一些最小长度的字符串。如果是这种情况,您可以定义一个体现该要求的类:

template <size_t min>
class MinString{
    std::string data;
public:
    friend std::istream &operator>>(std::istream &is, MinString &m) {
        std::string s;
        read_string(is, s); // rewrite read_string to take an istream & as a parameter
        if (s.length() >= min)
            m.data = s;
        else
            is.setstate(std::ios::failbit);
        return is;
    }

    operator std::string() { return data; }

    // depending on needs, maybe more here such as assignment operator
    // and/or ctor that enforce the same minimum length requirement

};

这导致代码如下:

Minstring<5> s;
while (infile >> s)
    process(s);

另一种可能性是你有正常的字符串,但在某些情况下你需要读取至少 5 个字符。在这种情况下,执行应该在函数中而不是类型中。

bool read_string_min(std::string &s, size_t min_len) { 
    read_string(s);
    return s.length() >= min_len;
}

同样,有了这个循环可以简单而干净:

while (read_string_min(s, 5))
    process(s);

也可以只编写一个函数来返回读取的长度,并在 while 循环中强制执行最小长度:

while (read_string(s) > 5)
    process(s);

有些人喜欢这个,因为它更符合单一责任原则。IMO,“读取至少 5 个字符的字符串”完全符合一项单一职责,因此我认为它充其量只是一个弱论点(但即使这种设计仍然可以很容易地干净地编写代码)。

摘要:任何输入的东西都应该隐式或显式地提供某种方式来验证它是否正确读取了输入。只是尝试读取一些输入但没有提供成功/失败指示的东西只是一个糟糕的设计(正是你的设计中明显的失败read_string导致了你遇到的问题)。

于 2016-03-11T17:00:25.447 回答
0

有第四个选项对我来说似乎更好:

string s;
while( read_string(s) && s.len() > 5 ) 
{
   //do something
}
于 2016-03-11T16:29:23.160 回答