当前位置: 首页 > news >正文

如何建设和优化网站上海网站建设公司网站建设

如何建设和优化网站,上海网站建设公司网站建设,网站后台管理系统设计,企业网站设计与优化开发中我们经常使用程序参数#xff0c;根据参数的不同来实现不同的功能。POSIX和GNU组织对此都制定了一些标准#xff0c;为了我们程序更为通用标准#xff0c;建议遵循这些行业内的规范#xff0c;本文介绍的开源库The Lean Mean C Option Parser就可以很好满足我们的需求…开发中我们经常使用程序参数根据参数的不同来实现不同的功能。POSIX和GNU组织对此都制定了一些标准为了我们程序更为通用标准建议遵循这些行业内的规范本文介绍的开源库The Lean Mean C Option Parser就可以很好满足我们的需求。 The Lean Mean C Option Parser在线文档(下载头文件和相关demo)The Lean Mean C Option Parser: Main Page (sourceforge.net) 一、优点 1.该库只有一个头文件只需要包含“#include optionparser.h即可” 2.该库是独立的没有任何依赖关系甚至不依赖C或C标准库 3.与getopt和派生函数不同它不会强制您按顺序循环使用选项使用更加便捷 二、选项语法 1.The Lean Mean C Option Parser 遵循POSIX getopt约定支持GNU风格的getopt_long长选项以及Perl风格的单减长选项getopt_long_only 2.短可选项的格式-X X是任意字符 3.短可选项的可以组合比如-X -Y 和 -XY是一样的 4.短可选项可以采用单独的或者附加方式取参数比如-X foo   -Xfoo 。如果注册X为长可选项 解析器就可以接受 -Xfoo 的格式 5.最后一个带参数的短可选项可以和其他的组合比如 -ABCXfoo  -ABCX foo (foo 是-X 可选项的参数) 6.长可选项的格式    -可选项名称 7.长可选项格式的可选项名称可以是任意名称包含任意字符即使“”也是可以的但是不建议这样做 8.长可选项可以缩写只要缩写是明确的。此外还可以设置缩写的最小长度 9.长可选项可以“-”“--”开始 10.长可选项可以采用单独的-option arg或者附加的-optionarg参数格式。附加格式中必须要使用“” 11.空字符串可以作为附加格式的长可选选项的参数“-option ”。作为参数的空字符串和完全没有参数之间的区别需要注意 12.允许将空字符串作为长可选项和短可选项的单独参数 13.短可选项和长可选项都可以以“-”字符开头。例如-X-X,     -X -X,     -long-X-X .这三种情况下 的参数都是 -X; 14.如果使用内置的Arg:Optional则必须附加可选项的参数 15.特殊选项–即没有名称终止选项列表。后面的所有内容都是非选项参数即使它以“-”字符开头。–本身不会出现在解析结果中 16.第一个不以“-”开头并且不属于前面的选项的参数将终止选项列表并且是第一个非选项参数。接下来所有命令行参数都被视为非选项参数即使它们以“-”开头。     注意这种行为是由POSIX强制执行的但GNU getopt只有在明确请求时例如通过设置POSIXLY_CORRECT才会执行。您可以通过将true作为第一个参数传递给例如Parser:parse来启用GNU行为。 17.看起来像选项即“-”后面至少有1个字符但实际上不是的参数不被视为非选项参数。它们被视为未知选项并被收集到用于错误报告的未知选项列表中。这意味着为了传递以减号字符开头的第一个非选项参数需要使用– 特殊选项例如     program -x -- --strange-filename  在这个例子中 –strange-filename 是非选项参数。如果前面的‘-’  没有它将被视为未知选项。 三、使用 熟悉以下几个类即可快速使用该库下面对这些类型进行介绍 1.Descriptor 描述一个选项、它的帮助文本用法以及应该如何解析它。下面是一个示例 enum OptionIndex {CREATE, ...}; enum OptionType {DISABLE, ENABLE, OTHER}; const option::Descriptor usage[] {{ CREATE, // indexOTHER, // typec, // shortoptcreate, // longoptArg::None, // check_arg--create Tells the program to create something. // help}, ... }; index解析器解析后该可选项所在数组的索引。建议使用枚举增强阅读性如上示例。 描述符具有相同索引的命令行选项将按照它们在命令行上出现的顺序出现在相同的链表中。如果有多个长选项别名引用同一个选项请为它们的描述符指定相同的索引。 如果你有意思完全相反的选项例如–enable foo和–disable foo你也应该给它们相同的索引但通过不同的类型值来区分它们。这样它们最终会出现在同一个列表中你就可以只取列表的最后一个元素并使用其类型。通过这种方式你可以稍后在命令行上的开关会覆盖以前的开关而无需手动编码 type用于区分相同index的可选项。 shortopt此字符串中的每个字符都将被接受为短选项字符。该字符串不得包含减号字符“-”否则将出现未定义的行为。如果此描述符不应包含短选项字符请使用空字符串“”。此处不允许使用NULL longopt长可选项名称。如果此描述符不应具有长选项名称请使用空字符串“”。此处不允许使用NULL虽然shortopt允许多个短选项字符但每个描述符只能有一个长选项名称。如果有多个长选项名称引用同一个选项请使用具有相同索引和类型的单独描述符。您可以在这样的别名描述符中重复短选项字符但没有必要这样做。 check_arg对于每个匹配shortopt或longopt的选项将调用此函数来检查该选项的潜在参数。 2.Arg 每个选项参数都有一个如此函数设置进Descriptor用于检查选项参数有效性。 typedef ArgStatus (*CheckArg)(const Option option, bool msg); 它用于检查选项是否可以接受潜在的参数。即使没有参数该函数也会被调用。在这种情况下option.arg将为NULL。 如果msg为true并且函数确定参数是不可接受的并且这是一个致命错误那么它应该在返回ARG_ILEGAL之前向用户输出一条消息。如果msg为false则该函数应保持静音否则将收到重复的消息。 ArgStatus的定义如下 ARG_NONE 选项没有参数。ARG_OK参数被选项接受。ARG_IGNORE该参数是不可接受的但这不是致命的因为该选项的参数是可选的。ARG_ILLEGAL参数不可以接受会有致命错误。目前已经预制了几个校验规则需要更为精准的校验规则可以自己定制例如 struct Arg: public option::Arg {static void printError(const char* msg1, const option::Option opt, const char* msg2){fprintf(stderr, ERROR: %s, msg1);fwrite(opt.name, opt.namelen, 1, stderr);fprintf(stderr, %s, msg2);}static option::ArgStatus Unknown(const option::Option option, bool msg){if (msg) printError(Unknown option , option, \n);return option::ARG_ILLEGAL;}static option::ArgStatus Required(const option::Option option, bool msg){if (option.arg ! 0)return option::ARG_OK;if (msg) printError(Option , option, requires an argument\n);return option::ARG_ILLEGAL;}static option::ArgStatus NonEmpty(const option::Option option, bool msg){if (option.arg ! 0 option.arg[0] ! 0)return option::ARG_OK;if (msg) printError(Option , option, requires a non-empty argument\n);return option::ARG_ILLEGAL;}static option::ArgStatus Numeric(const option::Option option, bool msg){char* endptr 0;if (option.arg ! 0 strtol(option.arg, endptr, 10)){};if (endptr ! option.arg *endptr 0)return option::ARG_OK;if (msg) printError(Option , option, requires a numeric argument\n);return option::ARG_ILLEGAL;} }; 3.Stats 确定用于Parser的缓冲区和选项数组的最小长度。因为Parser不使用动态内存所以必须预先分配其输出数组。如果您不想使用固定大小的数组可能会变得太小导致命令行参数被丢弃可以使用Stats来确定正确的大小。 buffer_max:真实参数个数 options_max:依赖Descriptor比Descriptor中的Index数量多一个。 4.Parser 检查参数的有效性并将其解析为更易于使用的数据结构。 int main(int argc, char* argv[]) {argc-(argc0); argv(argc0); // skip program name argv[0] if presentoption::Stats stats(usage, argc, argv);option::Option options[stats.options_max], buffer[stats.buffer_max];option::Parser parse(usage, argc, argv, options, buffer);if (parse.error())return 1;if (options[HELP])... optionsCount()返回有效选项数量 nonOptionsCount()返回非选项参数数量 error()返回是否存在解析错误。选项的非法参数即CheckArg返回ARG_ILEGAL是一个不可恢复的错误会中止解析。只有当CheckArg函数返回ARG_ILEGAL时未知选项才是错误。否则它们将被收集。 5.Parser 命令行中已解析的选项及其参数如果有。 Parser将具有相同Descriptor:索引的所有已解析选项链接在一起形成一个链表。这使您能够轻松实现处理重复选项和启用/禁用对的所有常见方法。 desc指向选项的Descriptor name选项的名称 arg选项的参数 namelen选项名称长度。 示例 //Test for presence of a switch in the argument vector: if ( options[QUIET] ) ... //Evaluate –enable-foo/–disable-foo pair where the last one used wins: if ( options[FOO].last()-type() DISABLE ) ... //Cumulative option (-v verbose, -vv more verbose, -vvv even more verbose): int verbosity options[VERBOSE].count(); //Iterate over all –filefname arguments: for (Option* opt options[FILE]; opt; opt opt-next())fname opt-arg; ... 四、整体示例 #include optionparser.h #include sstreamstruct Arg : public option::Arg {static void print_error(const char* msg1,const option::Option opt,const char* msg2){fprintf(stderr, %s, msg1);fwrite(opt.name, opt.namelen, 1, stderr);fprintf(stderr, %s, msg2);}static option::ArgStatus Unknown(const option::Option option,bool msg){if (msg){print_error(Unknown option , option, \n);}return option::ARG_ILLEGAL;}static option::ArgStatus Required(const option::Option option,bool msg){if (option.arg ! 0 option.arg[0] ! 0){return option::ARG_OK;}if (msg){print_error(Option , option, requires an argument\n);}return option::ARG_ILLEGAL;}static option::ArgStatus Numeric(const option::Option option,bool msg){char* endptr 0;if ( option.arg ! nullptr ){strtol(option.arg, endptr, 10);if (endptr ! option.arg *endptr 0){return option::ARG_OK;}}if (msg){print_error(Option , option, requires a numeric argument\n);}return option::ARG_ILLEGAL;}templatelong min 0, long max std::numeric_limitslong::max()static option::ArgStatus NumericRange(const option::Option option,bool msg){static_assert(min max, NumericRange: invalid range provided.);char* endptr 0;if ( option.arg ! nullptr ){long value strtol(option.arg, endptr, 10);if ( endptr ! option.arg *endptr 0 value min value max){return option::ARG_OK;}}if (msg){std::ostringstream os;os requires a numeric argument in range [ min , max ] std::endl;print_error(Option , option, os.str().c_str());}return option::ARG_ILLEGAL;}static option::ArgStatus String(const option::Option option,bool msg){if (option.arg ! 0){return option::ARG_OK;}if (msg){print_error(Option , option, requires an argument\n);}return option::ARG_ILLEGAL;}};enum optionIndex {UNKNOWN_OPT,HELP,SAMPLES,INTERVAL,ENVIRONMENT, };const option::Descriptor usage[] {{ UNKNOWN_OPT, 0, , , Arg::None,Usage: HelloWorldExample publisher|subscriber\n\nGeneral options: },{ HELP, 0, h, help, Arg::None, -h \t--help \tProduce help message. },{ UNKNOWN_OPT, 0, , , Arg::None, \nPublisher options:},{ SAMPLES, 0, s, samples, Arg::NumericRange, -s num, \t--samplesnum \tNumber of samples (0, default, infinite). },{ INTERVAL, 0, i, interval, Arg::NumericRange, -i num, \t--intervalnum \tTime between samples in milliseconds (Default: 100). },{ ENVIRONMENT, 0, e, env, Arg::None, -e \t--env \tLoad QoS from environment. },{ 0, 0, 0, 0, 0, 0 } };int main(int argc,char** argv) {argc - (argc 0);argv (argc 0); // skip program name argv[0] if presentoption::Stats stats(true, usage, argc, argv);std::vectoroption::Option options(stats.options_max);std::vectoroption::Option buffer(stats.buffer_max);option::Parser parse(true, usage, argc, argv, options[0], buffer[0]);try{if (parse.error()){throw 1;}if (options[HELP] || options[UNKNOWN_OPT]){throw 1;}const char* type_name parse.nonOption(0);if (parse.optionsCount() type_name buffer[0].name){throw 2;}}catch(int error){//deal error}return 0; }
http://www.hkea.cn/news/14497486/

相关文章:

  • 设计类型的网站云主机是什么
  • 网站建设上机考试wordpress win2012 r2
  • 济宁网站建设第一品牌中国物流网站
  • next.js做纯静态网站商务网站开发课程体会
  • 惠州网站制作维护做pc端网站用什么框架
  • 西宁专业做网站公司淘客怎么做推广网站
  • 旅游网站建设的摘要wordpress单页
  • 上海网站建设公设计师论坛
  • 福州网站建设信息关于网络营销的网站
  • 合肥官方网站优化费用如何建立一个网站 供客户选图
  • 一般做网站用什么字体广西教育平台网站建设
  • WordPress小说网站源码定制高端网站建设公司
  • 企业邮箱大全号码大全网站优化seo怎么做
  • 网站站长承德企业网站建设
  • 做网站可以用微软雅黑字体么南阳网站开发公司
  • 网站的手机客户端怎样做花瓣网是仿国外那个网站做的
  • 51网站空间还有吗wordpress+下载站
  • 西安创意网站建设网站开发服务税率是多少
  • 沈阳工程建设信息网站搜狗浏览器网页版入口
  • 做网站用什么后缀好十大免费最亏的免费app
  • 包站长ppt网站烟台seo关键词排名
  • 鄞州区建设局网站建立网络平台需要什么
  • 网站建设中模板奥联网站建设
  • php做简单网站教程i深建官方网站
  • 唐山网站建设设计福田瑞沃前四后四车价格
  • 进一步网站建设广告彩页设计
  • 网站留言系统编写代码免费域名注册申请
  • 网站源代码怎么上传聊城wap网站制作
  • 石家庄行业网站wordpress与typecho
  • 精品资源共享课网站建设网站方案范文