在"提升计划选项"中,如何判断是否指定了默认选项?



我正在编写一个程序,该程序需要大小,冗余和一些明文,并输出明文代码。我希望用于编码的大小和冗余

计算如下:
  • 如果未指定大小或冗余,则冗余为 3/7,并且大小应尽可能大。
  • 如果指定了大小但未指定冗余,则大小是指定的大小,冗余是将纯文本拟合为指定大小所产生的任何结果。如果明文小于该大小的 1/3,则存在错误,因为最大冗余为 2/3(2/3 和 3/7 来自汉明码)。如果明文太大,那也是一个错误。
  • 如果指定了冗余但未指定大小,则大小将达到所需的大小。
  • 如果同时指定了两者,则结果未定义。它可以与最后指定的一个一起使用,也可以任意选择一个。

代码在 https://github.com/phma/propolis;这是相关部分:

#include <boost/program_options.hpp>
#include <cstdio>
#include <fstream>
#include <iostream>
using namespace std;
namespace po=boost::program_options;
int lastSizeRed=0;
void onSize(int size)
{
lastSizeRed='s';
}
void onRed(string red)
{
lastSizeRed='r';
}
int main(int argc,char **argv)
{
int testflag=0,option_index=0,makedata=0;
bool geneletters=false;
int c,quality;
double redundancy=0;
int size=0;
string text,infilename,outfilename;
stringbuf filebuf;
string redundancyStr,formatStr,patternStr;
fstream infile;
int format=FMT_PS,pattern=0;
bool validCmd=true,helpFlag=false;
po::options_description generic("Options");
po::options_description hidden("Hidden options");
po::options_description cmdline_options;
po::positional_options_description p;
po::variables_map vm;
generic.add_options()
("size,s",po::value<int>(&size)->notifier(onSize),"Symbol size")
("redundancy,r",po::value<string>(&redundancyStr)->default_value("3/7")->notifier(onRed),"Redundancy (0,2/3]")
("text,t",po::value<string>(&text),"Text to encode")
("input,i",po::value<string>(&infilename),"File containing text to encode")
("output,o",po::value<string>(&outfilename),"Output file")
("format,f",po::value<string>(&formatStr)->default_value("ps"),"Output format")
("quality",po::value<int>(&quality)->default_value(1),"Quality of raster image (0-10)")
("pattern",po::value<string>(&patternStr),"Write a test pattern")
("writetables","Write decoding tables")
("geneletters","Optimize letters with genetic algorithm")
("test","Run tests")
("help","Show options");
initialize();
cmdline_options.add(generic).add(hidden);
debugletters=0;
try
{
po::store(po::command_line_parser(argc,argv).options(cmdline_options).positional(p).run(),vm);
po::notify(vm);
if (vm.count("test"))
testflag=1;
if (vm.count("writetables"))
makedata=1;
if (vm.count("geneletters"))
geneletters=true;
if (vm.count("help"))
cout<<"Usage: propolis [options]n"<<generic;
cout<<"count(size)="<<vm.count("size")<<" count(redundancy)="<<vm.count("redundancy")<<" lastSizeRed="<<lastSizeRed<<endl;
}
catch (exception &ex)
{
cerr<<ex.what()<<endl;
validCmd=false;
}
if (redundancyStr.length())
{
redundancy=parse_redundancy(redundancyStr);
if (redundancy>0 && vm.count("redundancy"))
size=0;
else
{
cerr<<"Could not parse redundancy: "<<redundancyStr<<endl;
validCmd=false;
}
}
if (formatStr.length())
{
format=formatnum(formatStr);
if (format<0)
validCmd=false;
}
if (patternStr.length())
{
pattern=patternnum(patternStr);
if (format<0)
validCmd=false;
}
}

我尝试vm.count"大小"和"冗余";无论是否指定,它都返回 1 表示"冗余"。我尝试为这两个选项添加notifier;它始终通知冗余,并首先通知冗余,即使在大小之后指定(./propolis -s 4 -r 1/2lastSizeRed设置为"s")。

解决方案是使用额外的解析器而不是通知器。如果未在命令行上指定默认值,则使用默认值调用通知程序;仅使用命令行选项调用额外的分析器。

pair<string,string> checkSizeRed(const string &s)
{
if (s.find("-s")==0 || s.find("--size")==0)
lastSizeRed='s';
if (s.find("-r")==0 || s.find("--red")==0)
lastSizeRed='r';
return make_pair(string(),string());
}
po::store(po::command_line_parser(argc,argv).options(cmdline_options)
.extra_parser(checkSizeRed).positional(p).run(),vm);

如果最后指定--sizelastSizeRed设置为 "s",如果最后指定--redundancy则设置为 "r",如果两者都未指定,则设置为 0。

最新更新