在我正在创建的控制台程序中,我有一些解析文件的代码。解析每一行后,将检查语法错误。如果存在语法错误,程序将停止读取文件并转到程序的下一部分。问题是,它非常困惑,因为到目前为止我唯一的解决方案是一系列嵌套的 if 语句或一行 if 语句。嵌套 if 的问题是它很快就会变得非常困惑,并且一系列 if 语句使程序测试了一些不需要测试的东西。这是我的问题的一些 sudo 代码(注意我没有使用 return 语句)
显示的是伪代码而不是真实代码,因为它非常大
嵌套如果:
open file;
read line;
//Each if is testing something different
//Every error is different
if (line is valid)
{
read line;
if (line is valid)
{
read line;
if (line is valid)
{
do stuff;
}
else
error;
}
else
error;
}
else
error;
code that must be reached, even if there was an error;
非嵌套 if:
bool fail = false;
open file;
read line;
//Each if is testing something different
//Every error is different
if (line is valid)
read line;
else
{
error;
fail = true;
}
if (!error && line is valid)
read line;
else
{
error;
fail = true;
}
if (!error && line is valid)
do stuff;
else
error;
//Note how error is constantly evaluated, even if it has already found to be false
code that must be reached, even if there was an error;
我查看了许多不同的网站,但他们的结论与我的问题不同。这段代码在运行时确实可以工作,但正如你所看到的,它不是很优雅。有没有人对我的问题有更可读/更有效的方法?如有任何帮助,我们将不胜感激:)
最佳答案
我想到了两个选择:
选项 1:链读取和验证
这类似于 std::istream
萃取运算符(operator)工作。你可以这样做:
void your_function() {
std::ifstream file("some_file");
std::string line1, line2, line3;
if (std::getline(file, line1) &&
std::getline(file, line2) &&
std::getline(file, line3)) {
// do stuff
} else {
// error
}
// code that must be reached, even if there was an error;
}
选项 2:拆分为不同的功能
这可能会有点长,但如果你正确地拆分内容(并给所有内容一个合理的名称),它实际上可以非常可读和可调试。
bool step3(const std::string& line1,
const std::string& line2,
const std::string& line3) {
// do stuff
return true;
}
bool step2(std::ifstream& file,
const std::string& line1,
const std::string& line2) {
std::string line3;
return std::getline(file, line3) && step3(line1, line2, line3);
}
bool step1(std::ifstream& file,
const std::string& line1) {
std::string line2;
return std::getline(file, line2) && step2(file, line1, line2);
}
bool step0(std::ifstream& file) {
std::string line1;
return std::getline(file, line1) && step1(file, line1);
}
void your_function() {
std::ifstream file("some_file");
if (!step0(file)) {
// error
}
// code that must be reached, even if there was an error;
}
这个示例代码有点太简单了。如果每个步骤中发生的行验证比 std::getline
更复杂的返回值(在进行实际输入验证时通常是这种情况),那么这种方法的好处是使其更具可读性。但如果输入验证就像检查 std::getline
一样简单,那么应该首选第一个选项。
关于c++ - "Cleaning up"嵌套 if 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47622208/