1.5.3 它是如何工作的
第一部分与上一个范例的代码非常相似,除了我们声明了更多变量。除此之外,我们还包含了另外一个头文件unistd.h,getopt()函数需要该头文件。我们使用getopt()函数来解析程序的选项。
还有另一个看起来很奇怪的新增内容,也就是代码的第一行:
我们将在本书后续内容中详细介绍这一点。目前,我们只需要知道它是我们用来遵守XOPEN标准的功能宏。当然,并非必须包含这一行。如果没有这一行,程序也可以在Linux下正常工作。但是如果我们编译程序并显示所有的警告消息(后续我们将学习如何操作)同时设置特定的C标准,那么,如果不包含这行代码,我们将会看到关于函数getopt隐式声明的警告。好的编程做法是添加这一行代码。当然,你可能会问,我怎么知道这些?这是因为在getopt()的手册页中有相关说明,我们将在下一个范例中进行详细的介绍。
getopt()函数
本范例的第二步是最令人兴奋的部分。在这一步,我们将使用getopt()函数来解析选项。函数getopt()代表获取选项。
使用getopt()的方法是在while循环中遍历所有参数,并使用switch语句捕获选项。让我们仔细看看while循环并将其分解为更小的部分:
getopt()函数返回它所解析的选项的实际字母。这意味着opt = getopt这一部分会将选项保存到opt变量中,不过仅仅保存实际字母。例如,-h将被保存为h。
然后,我们需要给getopt()函数传递参数,也就是argc(参数个数)、argv(实际参数)。最后是应该接受的选项(这里是smh,转换一下就是-s、-m和-h)。
最后一点,!= -1被用于while循环。当getopt()没有更多选项返回时,它将返回-1,表示已完成选项解析。这种情况下,while循环将结束执行。
while循环内部
在循环内部,我们使用switch语句为每个选项执行特定操作。在每个分支(case)下,我们执行计算并在计算完成后执行break退出分支。就像上一个范例一样,我们使用atoi()将参数字符串转换为整数。
在h分支下(-h选项,寻求帮助),我们打印帮助消息并返回代码0。我们请求帮助信息,因此它不是错误。但在h分支之下有一个默认分支,如果没有其他选项匹配,那么默认分支将会捕获这种情况,也就是说,用户输入了一个不被接受的选项。这确实是一个错误,所以在这里,我们返回代码1,表示出现了错误。
帮助信息函数
帮助消息应该显示程序所使用的各种选项、参数,以及简单的示例。使用printf(),我们可以在代码中将较长的行拆分为多个较短的行,就像我们在范例中所做的那样。唯一的字符序列\n是一个换行符。无论换行符位于什么位置,都会将对应的行换行。
编译和运行程序
在这个范例中,我们使用Make编译程序。相应地,Make实用程序使用了cc(一个链接到gcc的符号链接)。在本书的后续内容中,我们将学习如何通过在Makefile中编写规则来改变Make的行为。
我们尝试运行这个程序。首先,我们在没有任何选项或参数的情况下运行它,导致程序退出并显示帮助文本(返回值为1)。
我们尝试两个选项:-s对所有整数求和,-m将所有整数相乘。