【问题标题】:How to Repeat Execution from Main function after an Iteration迭代后如何从主函数重复执行
【发布时间】:2018-03-04 06:57:04
【问题描述】:

所以我有一个简化布尔表达式的程序。我想要实现的是,在第一个表达式的简化结束时,我希望用户选择是要简化另一个表达式还是退出控制台应用程序(程序)。

这是 Main 函数的代码

int main(int argc, char *argv[]) {

/* allow command line calling with arguments -m -b X
where X is a number. order or -m and -b X does not
matter*/
cout << "\Designed By a Student For the Students :)\n";
char choice;
do
{
    cout << "\nEnter the number of variables to be Minimized\n";
    cin >> m;
    if (argc >= 2)
    {
        string arg = argv[1];
        if (arg.find("-m") != -1) {
            show_mid = true;
            if (argc >= 3) {
                arg = argv[2];
                if (arg.find("-b") != -1)
                    MIN_BIT = atoi(argv[3]);
            }
        }
        else if (arg.find("-h") != -1) {
            cout << "-b X\tminimum bits should be X.\n"
                << "-m  \tshow mid process computation.\n"
                << "-h  \tshow this.\n";
                                     return 0;


        }
        else {
            if (arg.find("-b") != -1 && argc >= 3)
                MIN_BIT = atoi(argv[2]);

            if (argc >= 4) {
                arg = argv[3];
                if (arg.find("-m") != -1)
                    show_mid = true;
            }
            else
            {
                cout << "Invalid argument\n"
                    << "-b X\tminimum bits should be X.\n"
                    << "-m  \tshow mid process computation.\n"
                    << "-h  \tshow this.\n";
                                            return 0;

            }
        }
    }

    getinput();
    init();
    cout << "Press 'y' to Reduce Another Expression or 'n' to Close this Application";
    cin >> choice;
} while (choice == 'y');
WINPAUSE;
return 0;

}

正如您在上面看到的,我为此目的使用了一个 do while 循环,但我在这里面临两个问题,即程序在没有用户输入的情况下终止,如果我使用 WINPAUSE,当我按下任意键时程序将退出。递归是答案吗,请提出解决方法。

注意:我使用的是 VS2017 IDE..:)

编辑:新代码

int main(int argc, char *argv[]) {

/* allow command line calling with arguments -m -b X
where X is a number. order or -m and -b X does not
matter*/
cout << "\Designed By a Student For the Students :)\n";
char choice;
    if (argc >= 2)
    {
        string arg = argv[1];
        if (arg.find("-m") != -1) {
            show_mid = true;
            if (argc >= 3) {
                arg = argv[2];
                if (arg.find("-b") != -1)
                    MIN_BIT = atoi(argv[3]);
            }
        }
        else if (arg.find("-h") != -1) {
            cout << "-b X\tminimum bits should be X.\n"
                << "-m  \tshow mid process computation.\n"
                << "-h  \tshow this.\n";


        }
        else {
            if (arg.find("-b") != -1 && argc >= 3)
                MIN_BIT = atoi(argv[2]);

            if (argc >= 4) {
                arg = argv[3];
                if (arg.find("-m") != -1)
                    show_mid = true;
            }
            else
            {
                cout << "Invalid argument\n"
                    << "-b X\tminimum bits should be X.\n"
                    << "-m  \tshow mid process computation.\n"
                    << "-h  \tshow this.\n";

            }
        }
    }
    do
    {
        cout << "\nEnter the number of variables to be Minimized\n";
        cin >> m;
        getinput();
        init();
        cout << "Press 'y' to Reduce Another Expression or 'n' to Close this Application";
        cin >> choice;
    } while (choice == 'y');
WINPAUSE;
return 0;

}

编辑:这是 getinput() 和 init() 的代码

void getinput() {
unsigned in;
int num_bits = 0;
cout << "\nInput value followed by ENTER[^D ends input]\n> ";
while (cin >> in) {
    input_values.push_back(in);
    num_bits = count_bits(in);
    if (num_bits>MIN_BIT)
        MIN_BIT = num_bits;
    cout << "> ";
}
}
/*return min number of bits a number is represented by. used for best output*/
unsigned count_bits(unsigned n) {
    short bit = 0;
    int count = 0;
    while (n>0) {
        bit = n % 2;
        n >>= 1;
        count++;
    }
    return count;
}


void init() {
table.resize(1);
p_group.resize(1);
final_group.resize(1);
create_table();
print_table();
create_p_group();
if (show_mid)
    print_p_group();
create_final_group();
print_final_group();

}

【问题讨论】:

  • 如果您打算致电main(),请不要这样做,这是禁止的(未定义行为)。
  • 任何键,包括'y'?
  • 由于您在 else if 和 else 块中有 return 0...程序终止...删除它们...
  • @VijayKalmath 是的,包括“y”
  • 唉,大量不明智的全局变量使这变得相当模糊。我看到的两个return-s 用于转储使用指南,然后终止程序(完全合理)。当 命令行参数(不是用户提示)不是您所期望的时,它们会触发。 m 的值在您通过命令行启动参数之前是毫无价值的,您似乎出于某种原因对每次迭代都进行了重新处理。坦率地说,这些全局变量的所有设置可能最好在此循环之外完成。

标签: c++ loops recursion main do-while


【解决方案1】:

你的逻辑在很多地方都有缺陷,虽然一堆全局变量使它有些模糊,但有些事情是清楚的:

  • 在每次迭代时停止重新处理命令行参数。
  • 意识到char 的格式化提取不会跳过空格

如果您正确解析命令行参数,则前者可能是正确的。简而言之,如果您发现程序在到达循环之前终止,则意味着您的命令行参数不正确,或者您的解析逻辑已损坏

后者是阻止您的循环正确终止的原因。除非使用整行数据(包括尾随换行符),否则您之前格式化的输入将在输入流上至少留下一个换行符。如果不清除它,为choice 读取的格式化字符将简单地使用它,这显然不是'y' 的值。为了适应这种情况,在读取choice 之前,通过任何换行符丢弃输入流中的任何数据。注意:如果您的输入处理使用像 std::getline 这样的东西,它会消耗(并丢弃)换行符,则不需要此步骤。

你的循环应该是这样的:

int main(int argc, char *argv[])
{
    /* configure command line argument settings ONCE */
    if (argc >= 2)
    {
        string arg = argv[1];
        if (arg.find("-m") != -1) {
            show_mid = true;
            if (argc >= 3) {
                arg = argv[2];
                if (arg.find("-b") != -1)
                    MIN_BIT = atoi(argv[3]);
            }
        }
        else if (arg.find("-h") != -1) {
            cout << "-b X\tminimum bits should be X.\n"
            << "-m  \tshow mid process computation.\n"
            << "-h  \tshow this.\n";
            return 0;

        }
        else {
            if (arg.find("-b") != -1 && argc >= 3)
                MIN_BIT = atoi(argv[2]);

            if (argc >= 4) {
                arg = argv[3];
                if (arg.find("-m") != -1)
                    show_mid = true;
            }
            else
            {
                cout << "Invalid argument\n"
                << "-b X\tminimum bits should be X.\n"
                << "-m  \tshow mid process computation.\n"
                << "-h  \tshow this.\n";
                return 0;
            }
        }
    }

    cout << "Designed By a Student For the Students :)\n";
    char choice = 'y';
    do
    {
        cout << "\nEnter the number of variables to be Minimized\n";
        if (cin >> m)
        {
            getinput();
            init();
            cout << "Press 'y' to Reduce Another Expression or 'n' to Close this Application";

            // flush through eoln, read prompt
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            if (!(std::cin >> choice))
                break;
        }
        else
        {   // could not extract a valid value for m. not much more we can do.
            break;
        }

    } while (choice == 'y');
    return 0;
}

【讨论】:

  • @VijayKalmath 应该不需要在这个循环中。根据设计,两种输入提取都将在失败时终止循环。通常,如果您正在执行格式化输入并希望跳过无法破译的数据,则需要使用 clear+ignore 配对;在这种情况下不是。
  • 在我的帖子中加入我对您之前回复的回答,第一个“m”可以根据用户的意愿(在 getinput() 中定义)在每次迭代中更改,并且我已经定义了一个宏计算取决于 'm' 的 MIN_BIT 的值,该值也随着主函数的每次迭代而变化。如果我在这方面没有说清楚,请告诉我。
  • 我是新手,你的代码更简洁:-) @WhozCraig
  • @chrisstone 这个答案做了两件事:(1)处理命令行参数(如果有的话)来设置你的全局变量,然后(2)进入一个循环来处理m的输入值,然后您的getinput()init() 操作,并通过提示输入'y' 或非'y' 有条件地继续循环。据我了解,这正是您所需要的。没有理由重复处理您的命令行参数。如果命令行处理期间的某些设置依赖于m,则应将其简明扼要地移入循环中。
  • 哦,好吧,我明白那个克雷格了。但是现在它不会重复迭代,并且无论我的输入如何,控制台应用程序都会关闭:(
【解决方案2】:

将检查命令行参数的部分移到你的for循环之前,像这样:

cout << "\nEnter the number of variables to be Minimized\n";
cin >> m;
if (argc >= 2)
{
        string arg = argv[1];
        ...
        else
        {
            cout << "Invalid argument\n"
                << "-b X\tminimum bits should be X.\n"
                << "-m  \tshow mid process computation.\n"
                << "-h  \tshow this.\n";
            return 0;
        }
    }
}

do
{
    // your logic, init(), etc.
    cout << "Press 'y' to Reduce Another Expression or 'n' to Close this Application\n";
    cin >> choice;

} while (choice == 'y');

然后是你的

你有很多这样的陈述:

if (arg.find("-m") != -1)

您应该按照std::string::find 中的建议使用string::npos 来测试是否找不到匹配项。所以把它们改成这样:

if (arg.find("-m") != string::npos)

我必须让主函数无效

没有。

不要那样做。 What should main() return in C and C++? int 就是答案。

【讨论】:

  • 是的..告诉他同样的事情......感谢完整地编写它。
  • 非常感谢 gsamaras 和 @Vijay_Kalmath 成功了。但是有一个问题,当我按 y 时,控制台应用程序会重新启动,而我希望它在同一个屏幕上继续。有什么想法吗?
  • @chrisstone 你的意思是它停止(你的程序退出循环)?
  • @gsamaras 是的,当输入不是“y”时,它存在循环。我想再次指出我正在设计一个控制台应用程序,因此当输入为“y”时,当前控制台关闭并打开一个新的控制台。我的问题是,有什么办法可以在不重新开始的情况下继续使用同一个控制台?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2015-06-22
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
相关资源
最近更新 更多