由库代劳
很多程序都会使用命令行选项,因此有一个专门的库函数,可以用它来简化处理过程。这个库函数叫
getopt() ,每一次调用都会返回命令行中下一个参数。
看一下它是怎么工作的,假设程序能够接收一组不同的选项:
C 标准礼貌指南
unistd.h 头文件不属于 C 标准库,而是 POSIX 库中的一员。POSIX 的目标是创建一套能够在所有主流操作系统上使用的函数。
程序需要两个选项,一个选项接收值,-e 代表“引擎”;另一个选项代表了开或关,-a 代表“无敌模式”。可以循环调用 getopt() 来处理这两个选项,像这样:
在循环中,用 switch 语句处理每个有效选项。字符串 ae: 告诉 getopt() 函数“a 和 e 是有效选项”,e 后面的冒号表示“-e 后面需要再跟一个参数”,getopt() 会用 optarg 变量指向这个参数。
循环结束以后,为了让程序读取命令行参数,需要调整一下 argv 和 argc 变量,跳过所有选项,最后 argv 数组将变成这样:
经过一番处理,0 号参数不再是程序名了。argv[0] 会指向选项后的第一个命令行参数。
披萨拼图
有人偷吃了我们的代码披萨,你能补全披萨并复原 order_pizza 程序吗?
披萨拼图解答
有人偷吃了我们的代码披萨,请补全披萨并复原 order_pizza 程序。
试驾
现在就试试“点披萨”程序吧:
程序正确运行了!
好啦,这一章你学了不少东西,不但深入理解了标准输入、标准输出和标准错误,而且学会了使用重定向和自己创建的数据流读写文件。最后,还学会了处理命令行参数和选项。
C 程序员不是在创造小工具,就是在创造小工具的路上,Linux 中大部分小工具都是用 C 语言写的。精心设计小工具,确保它们做一件事并把它做好。假以时日,你就能成为一名卓越的 C 程序员。这里没有蠢问题问:我能合并两个选项吗?例如用-td now 代替-d now –t 。答:可以,getopt() 函数会全权处理它们。问:我可以改变选项之间的顺序吗?答:可以,因为我们用循环读取选项,所以-d now -t 、-t -d now 、-td now 都一样。问:也就是说,只要程序在命令行看到一个前缀为-值,就会把它当成选项处理?答:是的,前提是它必须在命令行参数之前出现。问:如果我想在命令行参数使用负数怎么办?像 set_temperature -c -4 ,程序会把 4 当作选项吗?答:为了避免歧义,可以用-- 隔开参数和选项,比如 set_temperature -c -- -4 。getopt() 看到--就会停止读取选项,程序会把后面的内容当成普通的命令行参数读取。
要点
main() 函数有两个版本,一个有命令行参数,一个没有。
命令行参数通过两个变量传递给 main() 函数,一个是参数的计数,另一个是指针(指向参数字符串)数组。
命令行选项是以“- ”开头的命令行参数。
getopt() 函数会帮助你处理命令行选项。
为了定义有效的选项,可以传给 getopt() 一个字符串,例如 ae: 。
选项之后的 “:”(冒号)表示该选项需要接收一个参数。
getopt() 会用 optarg 变量记录选项参数。
读取完全部的选项以后,应该用 optind 变量跳过它们。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论