Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++中解析主函数的大量输入的正确方法_C++_Xml_Class_Coding Style_Main - Fatal编程技术网

C++中解析主函数的大量输入的正确方法

C++中解析主函数的大量输入的正确方法,c++,xml,class,coding-style,main,C++,Xml,Class,Coding Style,Main,假设有30个数字必须输入到一个可执行文件中,由于输入量很大,通过命令行输入它们是不合理的。一种标准方法是将它们保存到单个XML文件中,并使用类似tinyxml2的XML解析器来解析它们。问题是,如果我使用tinyxml2直接解析输入,我将有一个非常臃肿的主函数,这似乎是常见的好做法 例如: int main(int argc, char **argv){ int a[30]; tinyxml2::XMLDocument doc_xml; if (doc_xml.Lo

假设有30个数字必须输入到一个可执行文件中,由于输入量很大,通过命令行输入它们是不合理的。一种标准方法是将它们保存到单个XML文件中,并使用类似tinyxml2的XML解析器来解析它们。问题是,如果我使用tinyxml2直接解析输入,我将有一个非常臃肿的主函数,这似乎是常见的好做法

例如:

int main(int argc, char **argv){

  int a[30];      

  tinyxml2::XMLDocument doc_xml;

  if (doc_xml.LoadFile(argv[1])){
    std::cerr << "failed to load input file";
  }
  else {
    tinyxml2::XMLHandle xml(&doc_xml);

    tinyxml2::XMLHandle a0_xml =
        xml.FirstChildElement("INPUT").FirstChildElement("A0");

    if (a0_xml.ToElement()) {
      a0_xml.ToElement()->QueryIntText(&a[0]);
    }
    else {
      std::cerr << "A0 missing";
    }

    tinyxml2::XMLHandle a1_xml =
        xml.FirstChildElement("INPUT").FirstChildElement("A1");

    if (a1_xml.ToElement()) {
      a1_xml.ToElement()->QueryIntText(&a[1]);
    }
    else {
      std::cerr << "A1 missing";
    }

    // parsing all the way to A29 ... 
  }

  // do something with a

  return 0;
}

处理它的最佳方法是什么?

注意,除了读取XML文件,您还可以通过stdin传递大量数据。使用例如mycomplexcmd | hextump-C是非常常见的做法,其中hextump通过管道从stdin读取数据

现在讨论问题的其余部分:这里有一个使用多函数示例的理由,不管它们是构造函数还是普通函数,都不是很重要。这与为什么您希望任何函数都更小——可读性几乎是一样的。也就是说,我不知道常见的良好实践,我见过许多终端公用设施都有非常大的主管道

想象一下,有人在读main的第一个变体。他们将经历一系列的麻烦,弄清楚所有这些句柄、查询、孩子、父母——而他们只想看看后面的部分//用a做点什么。这是因为他们不知道这是否与他们的问题有关。但是在第二个变体中,他们会很快找到答案啊哈,这是解析逻辑,不是我要找的

也就是说,你当然可以用详细的评论来打破逻辑。但是现在想象一下出了什么问题,有人在调试代码,他们把问题归咎于这个函数好吧,考虑到这个函数是main函数,这很有趣,也许他们刚刚开始调试。这个bug非常微妙,不清楚,需要检查函数中的所有内容。现在,因为你在处理可变语言,你经常会发现自己处于这样一种情况,你认为,哦,可能是因为这个变量,它正在改变?;首先通过这个大函数查找变量的每一个用法,然后查找可能导致变量改变的块的条件;然后你要弄清楚,这又是一个与条件相关的大模块,它可以被提取到一个单独的函数中,其中使用了哪些变量;直到你弄明白它在做什么的那一刻,你已经忘记了你之前看到的一半

当然,有时大型功能是不可避免的。但是如果你问这个问题,那可能不是你的问题

经验法则:你看到一个函数做两件不同的事情,几乎没有共同点,你想把它分成两个不同的函数。在您的例子中,它是解析XML并使用。虽然如果第二部分是几行,可能不值得提取-推测一下。不要担心开销,编译器擅长优化。您可以使用LTO,也可以仅将.cpp文件中的函数声明为静态非类静态,并且根据优化选项,编译器可以内联代码


附言:你似乎处在一个非常有用的状态,学习和哈斯克尔一起玩。你不必将其用于真正严肃的项目,但你所获得的见解可以应用于任何地方。它迫使您进行更好的设计,尤其是当您需要将一个功能从许多其他事情中分离出来时,您会很快感觉到这一点。

您似乎没有足够的经验来衡量代码的可重用性要求。例如,在您让我们知道数据代表什么以及应用程序计划如何处理数据之前,我们无法提供有关此类决策的建议。例如,数据是否为将来多个应用程序将使用的某种通用文件格式?如果你提供这类信息,我可以告诉你你需要知道的确切情况。在它可重用之前,它必须是usable@didiz确切地OP过于担心这一点是他困惑的原因。然而,在这一点上,对于某些人来说,最好的方法是让经验更丰富的程序员建立他们的情况下的可重用性需求。@rationalcoder这显然是一个非常简单的例子。实际上,它不仅仅是30个整数,它是图像、外部/内部矩阵参数、布尔标志等的组合。让我们假设其他可执行文件E1使用a的一部分,如A0~A10和B0~B5,可执行文件E2使用A5~A25。除此之外,没有其他可执行文件使用A0~A29。这些信息足以让你给出答案吗?@rationalcoder给你一个非常简单的例子。一个程序有两个整数A0~A1作为输入,另一个程序有一个整数A0和一个浮点B0作为输入,这是完全正常的,对吗?这当然不是设计缺陷。为什么?
他们应该是同一个节目吗?谢谢你的见解。将解析代码移动到main.cpp中的自由函数中,您认为如何?这种方法能充分利用这两种变体吗?@user3667089这就是我要做的,因为与类相比,它会产生更少的代码。类是一个抽象,必要时是抽象的。你不会想为代码中的每一步都创建一个类吧?问问自己:你为什么需要上课?您需要将一些成员分组吗?它是否会使您的代码更简洁、可读性更强?例如,如果您是从其他类继承的,而这些类并不总是可以改进事情?如果你盲目地到处乱扔抽象概念,它不会神奇地让你的代码变得更好,没有这样的灵丹妙药。
int main(int argc, char **argv){

  int a[30];      

  ParseXMLJustForThisExeClass ParseXMLJustForThisExeClass_obj;

  ParseXMLJustForThisExeClass_obj.Run(argv[1], a);

  // do something with a

  return 0;
}