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

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

本文关键字:函数 任务 goto 何使用 执行 文件      更新时间:2023-10-16

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

换句话说,我

故意试图远离任何普遍认为好的编程,我正在尝试其他方法......

话虽如此,我遇到了我的第一个问题。我想从文件中读取,并通过简单地将我收集的数据传输到代码的另一部分来模拟"函数"。运行它...并返回到文件。

以下是我的一些代码,以便您可以了解我正在尝试执行的操作的基本概念:

#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 语句试图完成的。如果您忽略该警告,则会遇到可能会在分配/初始化之前或释放之后使用myFile的情况(这非常糟糕(。我建议您将if (command == "function")代码块移动到else if (command == "file")范围内。

一些一般性建议:

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

2(goto在C中很糟糕,在C++中甚至更糟,因为在C++中,你有各种隐式内存操作,你可以在C中轻松避免。所以也许你想用 C 重写该代码,然后你就不会收到错误/警告。

示例中的

问题是跳过ifstream构造函数。

真是:GOTO语句在某些情况下可以使用。例如,根据MISRA C++ 2008

规则 6-6-1(必填( GOTO 语句引用的任何标签应在同一个块中声明,在包含 GOTO 的块中声明陈述。

规则 6-6-2(必需( GOTO 语句应跳转到标签稍后在同一函数体中声明。

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

为什么会有这些规则?

GOTO 的问题在于它破坏了代码的执行顺序。人类在想象计算机程序将如何参与时间方面非常糟糕。如果您使用 GOTO,程序不会更改行顺序,而是跳转。这是许多可怕错误的原因。参见E. W. Dijkstra的"GOTO声明被认为是有害的"。

清理

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

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

而不是写:

ifstream myFile(fileName.c_str());

您应该将ifstream变量声明到main()的顶部,如下所示:

ifstream myFile;

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

myFile.open(fileName.c_str());

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