c++ - "Cleaning up"嵌套 if 语句

标签 c++ performance file if-statement nested-if

在我正在创建的控制台程序中,我有一些解析文件的代码。解析每一行后,将检查语法错误。如果存在语法错误,程序将停止读取文件并转到程序的下一部分。问题是,它非常困惑,因为到目前为止我唯一的解决方案是一系列嵌套的 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/

相关文章:

python - 性能问题 : big numpy array and system call

c++ - 从文件末尾检索字符串时失败

C++ "dynamic"数组

mysql - 远程mysql服务器速度

php - 多数据库还是单数据库?

java - 如何从 FileDialog 获取绝对路径?

php - 使用 PHP Regex 编辑 CSS 文件

c++ - 以Bitcode保存文件加密

c++ - 如何将用户返回到模拟之前的状态?

c++ - 如何使用 CheckMultisampleQualityLevels 并启用多重采样