我如何使用 goto 来执行文件任务而不是使用函数?

How can I use goto to perform a task for a file instead of using a function?

所以我一直听说使用 goto 会让你成为一个糟糕的人,所以直到最近我才真正尝试过它。为了好玩,我决定制作一个 HEAVILY 依赖 goto 语句的程序,以亲眼看看它们何时可以派上用场。

换句话说,我有意远离任何被普遍认为是好的编程的东西,并且我正在尝试其他方法...

话虽如此,我 运行 进入了我的第一期。我想从一个文件中读取,并通过简单地 t运行 将我收集的数据转移到我的代码的另一部分来模拟 "function".. 运行 它通过...和 ​​return回到文件。

这是我的一些代码,因此您可以了解我正在尝试做的事情的基本概念:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    string command, fileName, fileLine;

    while (command != "quit")
    {
        cout << "cmd> ";
        cin >> command;

        if (command == "function")
        {
            FUNCTION: // I want to manipulate the data I gather from the file here.

            cout << "Perform a certain task here instead of using a function." << endl;

            goto FILE;
        }

        else if (command == "file")
        {
            cout << "filename> ";
            cin >> fileName;

            ifstream myFile(fileName.c_str());

            if (myFile.is_open())
            {
                while (getline(myFile, fileLine))
                {
                    goto FUNCTION;

                    FILE:

                    cout << "You finished your task using the above 'if' statement." << endl;
                }

                myFile.close();
            }
        }

        else if (command == "quit")
            break;

        else
            cout << "Invalid Command." << endl;
    }

    return 0;
}

当我尝试编译我的代码时,出现以下错误:

example.cpp: In function ‘int main()’:
example.cpp:37:6: error: jump to label ‘FILE’ [-fpermissive]
example.cpp:21:9: error:   from here [-fpermissive]
example.cpp:29:13: error:   crosses initialization of ‘std::ifstream myFile’

好像不能用goto跳过“ifstream myFile”的初始化。有谁知道一种方法,不使用函数也不使用任何标志,我可以使用 goto?

完成此任务

问题正如编译器告诉您的那样...您不能跳过 ifstream myFile(fileName.c_str()); 的初始化,而这正是您的 goto 语句试图完成的。如果您忽略该警告,您可能会在 allocated/initialized 之前或释放之后使用 myFile(这非常糟糕)。我建议您将 if (command == "function") 代码块移动到 else if (command == "file").

的范围内

一些一般性建议:

1) goto 在 C 代码中大量用于清理。您可以浏览 linux 内核并查看大量示例 1 2 3

2) goto 在 C 中很糟糕,在 C++ 中更糟,因为在 C++ 中你有各种各样的隐式内存操作,你可以在 C 中轻松避免。所以也许你想在 C 中重写代码然后你不会得到 error/warning.

您的示例中的问题是您跳过了 ifstream 构造函数。

正确的是:GOTO语句在某些条件下可以使用。例如根据 MISRA C++ 2008

Rule 6-6-1 (Required) Any label referenced by the GOTO statement shall be declared in the same block, on in a block enclosing the GOTO statement.

Rule 6-6-2 (Required) The GOTO statement shall jump to a label declared later in the same function body.

这两条规则是最重要的,但还有其他规则。

为什么要制定这些规则?

GOTO 的问题在于它打乱了代码执行的顺序。人类很难想象计算机程序将如何随时间变化。如果您使用 GOTO,程序不会按照行顺序而是跳转。这是许多可怕错误的原因。请参阅 E. W. Dijkstra 的“GOTO 语句被认为是有害的”。

清理

GOTO 有时用于清理。然而,这被认为是一种糟糕的风格,因为人们应该依赖 RAII 习惯用法。例如当抛出异常时,清理可能不会被处理。

我找到了问题的解决方案。

而不是写作:

ifstream myFile(fileName.c_str());

您应该像这样在 main() 的顶部声明 ifstream 变量:

ifstream myFile;

然后,读取文件名后,将其分配给输入文件流:

myFile.open(fileName.c_str());

这将允许您使用 goto 为文件执行任务而不是使用函数(没有 运行 我收到的错误)。