我如何使用 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
为文件执行任务而不是使用函数(没有 运行 我收到的错误)。
所以我一直听说使用 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
为文件执行任务而不是使用函数(没有 运行 我收到的错误)。