如何使用(或不使用?)goto in else - if

时间:2014-07-26 16:57:40

标签: c++

每次我使用ifgoto绕过一个进程并直接退出时,它不会绕过某个命令,但它只是结束。这是一个例子:

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string k;
  cout <<"What would you like to do ?\n"<<"Continue or Exit\n";
  cin >> k;
  if (k = "exit","Exit") goto s;
  else (k = "Continue","continue");
  cout << "You continued...";
  s:
  return 0
}

问题在于,即使您键入&#34;退出&#34;或者&#34;继续&#34;它只是简单地关闭。 有人能看到问题吗?另外,我怎么能避免使用goto?

5 个答案:

答案 0 :(得分:4)

第一个if始终为true,因为在分配之后,逗号运算符的RHS上的测试将为true

您的简单程序不保证使用goto。但是,对于处理此类任务,我的首选也是过度杀戮:功能表。

我结束了一个例子。我们从一个简单的回调类开始。回调接口带有一个默认实现,它抱怨输入。

struct Callback {
    virtual ~Callback () {}
    virtual void operator () (std::string k) const {
        std::cout << "Unrecognized input: " << k << '\n';
    }
};

这部分定义了函数表数据结构,声明了一个API来初始化一个,以及调用回调的驱动代码:

typedef std::map<std::string, const Callback *> CallbackMap;

static void init_table (CallbackMap &cbmap);

static void invoke_table (const CallbackMap &cbmap, std::string k)
{
    CallbackMap::const_iterator i = cbmap.find(k);
    if (i != cbmap.end()) (*i->second)(k);
    else Callback()(k);
}

int main ()
{
    CallbackMap cbmap;
    std::string k;
    init_table(cbmap);
    std::cout << "What would you like to do?\nContinue or Exit\n";
    std::cin >> k;
    invoke_table(cbmap, k);
    return 0;
}

单个回调实现使用此辅助宏实现为单例:

#define CONST_SINGLETON(Name) \
    public: \
        static const Name & instance () { \
            static const Name one; \
            return one; \
        } \
    private: \
        Name () {} \
        Name (const Name &); \
        void operator = (const Name &)

每个回调实现都会执行示例程序中提供的简单操作:

class ExitCallback : public Callback {
    void operator () (std::string) const { std::exit(0); }
    CONST_SINGLETON(ExitCallback);
};

class ContinueCallback : public Callback {
    void operator () (std::string) const {
        std::cout << "You continued...\n";
    }
    CONST_SINGLETON(ContinueCallback);
};

初始化例程使用对应于相应回调的字符串填充函数表:

static void init_table (CallbackMap &cbmap)
{
    static struct { const char *s; const Callback *cb; } init[] = {
        { "exit", &ExitCallback::instance() },
        { "Exit", &ExitCallback::instance() },
        { "continue", &ContinueCallback::instance() },
        { "Continue", &ContinueCallback::instance() },
        { 0, 0 }
    };
    for (int i = 0; init[i].s; ++i) {
        cbmap[init[i].s] = init[i].cb;
    }
};

答案 1 :(得分:3)

1)此处不要使用goto:在现代C ++代码中使用它几乎不合适。

2)使用==来比较字符串(=用于string作业)

 if (k == "exit","Exit") 
      ^^^^
    //Here

 else (k == "Continue","continue")
      ^^^^
   // And here

3) ,不是“and”运算符,请使用:

if (k == "exit" || k == "Exit")

4)您有无用的括号,缩进代码以正确查看确实所需的块。

答案 2 :(得分:3)

您需要学习如何使用调试器,并且需要了解有关C ++的更多信息

if (k = "exit","Exit") goto s;   //VERY WRONG

并不代表你想要的东西:

尽可能至少代码k="exit"avoid goto

此外,启用所有警告(和调试信息)。也许你的编译器可能会警告你。

我建议你free software读取一些源代码(例如在sourceforge或其他地方)。这会教你很多。

答案 3 :(得分:1)

正确的缩进和样式将帮助您了解您的一些努力。

首先,我强烈建议将字符串转换为小写或大写字母。这样就无需检查字符串中大写和小写字母的所有排列:

  cout << "What would you like to do ?\n"
       << "Continue or Exit\n";
  cin >> k;
  std::transform(k.begin(), k.end(), k.begin(), tolower);

退出main函数,return一个值,例如EXIT_SUCCESS或EXIT_FAILURE。

  if (k == "exit")
  {
    return EXIT_SUCCESS;
  } // No goto's necessary
  // The code continues here.

记住'='是赋值,'=='是比较。

无需比较“继续”,因为如果响应不是“退出”,它会“自动”执行此操作。

使用goto
在此实例中goto的使用不推荐 如果你真的必须使用goto,你需要不止一个标签。

int main(void)
{
  string k;

top_of_loop:  // Label for your goto
  cout << "What would you like to do ?\n"
       <<"Continue or Exit\n";
  cin >> k;
  std::transform(k.begin(), k.end(), k.begin(), tolower);

  if (k == "exit")
  {
    goto end_of_program;
  }
  // Execution continues here automatically.

  else
  {
    if (k == "continue")
    {
       goto program_continuation;
    }
    else
    {
       cout << "Unknown response, try again.\n";
       goto top_of_loop;
    }
  }
program_continuation:
  cout << "You continued...";
  goto top_of_loop;

end_of_program:
  return 0
}

作为while循环

  cout << "What would you like to do ?\n"
       <<"Continue or Exit\n";
  cin >> k;
  std::transform(k.begin(), k.end(), k.begin(), tolower);
  while (k != "exit")
  {
    // Your program stuff here.
    cout << "Program continued.\n";

    // Prompt the User again.
    cout << "\n"
         << "What would you like to do ?\n"
         << "Continue or Exit\n";
    cin >> k;
    std::transform(k.begin(), k.end(), k.begin(), tolower);
  }
  return 0; // Exit main().

答案 4 :(得分:0)

您的代码反映了您的意图,但这些意图并非用C ++编写。它们是一个有效的C ++程序 - 它当然可以编译 - 但你的意思并不是你所写的。

这是固定做你想做的事。

int main()
{
  string k;
  cout << "What would you like to do ?\nContinue or Exit" << endl;
  cin >> k;
  if (! (k == "exit" || k == "Exit")) {
    if (k == "Continue" || k == "continue") {
      cout << "You continued...";
    }
  }
  return 0
}

你也可以这样做:

int main()
{
  string k;
  cout << "What would you like to do ?\nContinue or Exit" << endl;
  cin >> k;
  if (k == "exit" or k == "Exit") return 0;
  if (k == "Continue" or k == "continue") {
    cout << "You continued...";
  }
  return 0
}

更改如下:

  1. 要检查多个条件中的一个是否为真,请使用逻辑运算符来加入测试。运算符写为||,或者简称为or

  2. 比较运算符为==。您使用的运算符=是赋值运算符。它执行赋值,其结果值是赋值。

  3. 逗号运算符分隔要评估的多个表达式。它的结果值是 last 表达式,即使计算了所有表达式。例如,(1, 2, 3)的值为3