如何在交换机情况下消除goto的使用

Gir*_*are 3 c++

基本上我想接受来自用户的特定字符,然后使用switch case将它与该字符大小写相关的字符串传递给另一个函数.例如.

case i:strcpy(str,"ice-cream");
    other_function(str);
    break;
Run Code Online (Sandbox Code Playgroud)

如果用户打印了任何默认字符,那么它应该打印默认语句并再次从用户获取字符并检查其大小写.我这样做了goto,但是goto在此代码中是否还有其他选项可以避免或替换.

p:  
    {
        cout<<"Choose account type:-\n"<<"Enter\ns :-saving\nc :-current\nf :-fixed\nr :-recurring"<<endl;
        char c;
        cin>>c;
        switch(c)
        {
            char t[20];
        case 's':
             strcpy(t,"saving");
             a[i].setype(t);
             break;
        case 'c':
             strcpy(t,"current");
             a[i].setype(t);
             break;
         case 'f':
             strcpy(t,"fixed");
             a[i].setype(t);
             break;
         case 'r':
             strcpy(t,"reccurring");
             a[i].setype(t);
             break;
         default:
             cout<<"Enter valid account type"<<endl;
             goto p;
         }
     }
Run Code Online (Sandbox Code Playgroud)

Lig*_*ica 9

整个switch应该被放入一个函数中,它的返回值用于确定接下来循环发生了什么.

while (true) {
    std::cout << "Choose account type:\n" << std::flush;
    char c;

    if (cin >> c)
    {
       const bool result = HandleUserInput(a[i], c);
       if (result)
          break;
       else
          std::cout << "Enter valid account type\n";
    }
    else
    {
       // Input error - you'll want to do something about that
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

// Given a character representing an account type, sets
// the type of 'account' as appropriate. Returns false
// on failure.
bool HandleUserInput(Account& account, const char c)
{
    switch (c)
    {
        case 's':
           a[i].setype("saving");
           return true;

        case 'c':
           a[i].setype("current");
           return true;

        case 'f':
           a[i].setype("fixed");
           return true;

        case 'r':
           a[i].setype("recurring");
           return true;

        default:
           return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

(请注意我是如何摆脱的strcpy,这似乎不是必要的?取决于setype我猜想的是什么[拼错了].另外,对于奖励点,如果你不这样做,可以考虑使用地图而不是开关关心一点性能.)

拔示巴的建议是一个有效的选择,但我认为,一个return看起来更清晰的内switch比意志continue,因为后者有其他种类的控制流语句的含义之内,而前者从来不会.

另请注意,如果您出于某种原因决定使用某项功能,那么您的实际上并没有什么特别的错误,goto也不要让货物狂热分子告诉您!

  • 这是一个非常明智的选择.有一个upvote. (3认同)

Bat*_*eba 7

就在这里.由于continueswitch块(参见break)中没有直接含义,前者的存在将适用于适当的外环控制结构.

所以有些东西就行了

do {
    // your code here, starting with "Choose account type".

    ...

    default:
        std::cout << "Enter valid account type" << std::endl;
        continue; // back to the start of the do loop
    } // close the switch
    break; // fall out of the loop
} while (true);
Run Code Online (Sandbox Code Playgroud)

会做到这一点,并且是相当惯用的C++.

  • 在我看来不是惯用语(这是我10年来第一次看到这样的代码),但它很有趣! (3认同)