重定向到函数中的函数

Redirect to a function from a function

本文关键字:函数 重定向      更新时间:2023-10-16

在回答我之前,我目前正在学习C++,对C++只有一些了解。

这里有一个例子,用户将看到一个语言选择,用户必须在语言左侧键入数字才能选择,否则将再次返回到选择。

所以我有一个想法:先放main函数,最后放语言功能。但问题是因为main函数在language之前,所以main功能无法找到language

下面是示例代码:

int main() {
    language();                     // The main function redirect user to the language function
}
int language() {                    // The language() function 
    std::cout << "1 for cookie!";        
    std::cin >> choice;             // Ask user for choice
    if (choice == 1) {
        choice1();                  // If the choice is 1, user will be redirected to choice1() function
    } else {
        main()                      // Otherwise user will be redirected to main and of course, redirect to language() function again
    }
}

由于上面描述的问题,我在重建项目时收到了来自Code::Blocks IDE的警告:

错误:未在此作用域中声明"language"

是否有其他方法可以将用户从一个函数重定向到另一个函数?

编辑:当前的答案让我陷入了无限循环,这不是我想要看到的结果。我希望看到的结果是,如果用户键入了无效值,它将再次将用户重定向到用户当前所在的函数,并且代码必须只运行一次。(表示不是无限循环)

您需要在首次使用之前声明函数。

此外,如前所述,根据标准,您不得在程序中使用main:

不得在程序中使用功能主体。

因此,创建另一个函数并将当前工作封装在其中!

int language(); // DECLARATION
// You could also just define function before first usage:
void do_work()
{
    language();
}

int main() {
    do_work();                     // The main function redirect user to the language function
}
int language() {                    // The language() function DEFINITION
    std::cout << "1 for cookie!";        
    std::cin >> choice;             // Ask user for choice
    // If you enter the invalid input in cin (character for example)
    // you need to reset cin in order to allow user to enter new choice
    std::cin.clear(); 
    // don't forget to include <limits>
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');

    if (choice == 1) {
        choice1();                  // If the choice is 1, user will be redirected to choice1() function
    } else {
        do_work();                      // Otherwise user will be redirected to do_work and of course, redirect to language() function again
    }
}

注意:使用递归(这里有一个间接递归:do_work->language->do_work)进行循环(尤其是潜在的无限循环)可能很危险!请参阅其他答案,了解如何使用循环语句解决此问题!

EDIT如果您想检查整行,而不仅仅是第一个字符,您可以将整行读取为字符串,检查字符串的长度是否为1(用户只输入一个字符),然后您可以使用第一个字符进行切换:

include <iostream>
#include <limits>
#include <cstdlib>
#include <string>
int language(); // DECLARATION
// You could also just define function before first usage:
void do_work()
{
    language();
}

int main() {
    do_work();                     // The main function redirect user to the language function
}
int language() {                    // The language() function DEFINITION
    std::string choice;
    std::cout << "1 for cookie!";
    std::getline(std::cin, choice);
    if (choice.length() == 1 && choice.at(0) == '1') {
       choice1();                 // If the choice is 1, user will be redirected to choice1() function
    } else {
        do_work();                      // Otherwise user will be redirected to do_work and of course, redirect to language() function again
    }
}

您必须将函数的原型放在调用之前:

int language(); // Declare the function, it is the prototype of the function here
int main() {
    language();                     // The main function redirect user to the language function
}
int language() {                    // The language() function 
    std::cout << "1 for cookie!";        
    std::cin >> choice;             // Ask user for choice
    if (choice == 1) {
        choice1();                  // If the choice is 1, user will be redirected to choice1() function
    } else {
        // main(); // <- You cannot do this !!
        language(); // Use recursive code
    }
}

请注意,在下面的代码中:

  • 我在main之前添加了函数language();的原型
  • 我将调用更改为标准禁止的main,并使您的函数递归

由于我终于知道如何使用循环,我找到了一个更好、更容易的解决方案,可以要求用户重复输入,直到语句为true。

int input;
std::cin << input;
switch(input) {
    case '1':
        // do something...
        break;
    default:
        break;
}
while (input != '1') {
    std::cin << input;
    switch(input) {
        case '1':
            // do something...
            break;
        default:
            break;
    }
}

我写了一个代码,尝试了几次后再次显示菜单,但尝试了一次后,我删除了代码,无法再这样做了。上面的代码是类似的,没有计算用户尝试了多少次,但由于我的目标只是在用户输入有效值后重定向用户,并且不会导致程序进入无限循环,所以上面的代码非常完美。(我使用的是移动设备,所以我不知道上面的代码是否正常工作。)

您确实不想从另一个函数调用main。在C语言中,它在技术上是允许的,在C++中,它是"未定义的行为",因此你应该避免这样做。

相反,解决方案是围绕对主要语言的调用进行循环:

int main()
{
    int result = 0;
    do
    {
       result = language();
    } while(result != 0); 
}

然后让language函数在该"退出"时返回0,在应该继续时返回非零。

在main之前的某个地方使用函数原型,编写类似的代码:

void language();

然后,您可以在编译的文件中的任何位置编写函数的代码。

我会写这样的

do //forever
{
    int choice = 0;
    std::cout << "1 for cookie!";        
    std::cin >> choice;
    if (choice == 1)
    {
        choice1();
        break;
    }
} while (true)

所以我找到了一个解决方案,当用户键入除数字以外的任何类型的字符时,可以防止无限循环。

int main() {
    language();                     // The main function redirect user to the language function
}
void language() {                    // The language() function 
    char choice;
    std::cout << "1 for cookie!";        
    std::cin >> choice;             // Ask user for choice
    if (choice == '1') {
        choice1();                  // If the choice is 1, user will be redirected to choice1() function
    } else {
        language()                      // Otherwise user will be redirected to main and of course, redirect to language() function again
    }
}

我还发现我忘记为选项添加任何类型,对此感到抱歉。。。

if语句中,我将使用'1'而不是1,因为如果我不使用它,程序将"认为"这是而非1并引导用户使用else