1.问题回答
回答110.【C语言】编写命令行程序(1)文章的问题
问题:既然只检查"--version"和"-v"参数(都是第二个参数),直接写成下面代码不就行了吗?能达到同样的效果,为什么需要遍历参数数组?
例如:输入Commend.exe -h或Commend.exe -help来查看帮助;输入Commend.exe --host ip地址来存储主机的ip地址等等,如果参数过多,那就要手动判断argv[1],argv[2],..,argv[n]的值,有点麻烦,写成argv[i]更简单
2.实验1
使用遍历参数的方法来设计一个程序,在cmd中输入Commend.exe --version或Commend.exe -v来显示程序的版本,字符串"The Commend.exe's version is 1.0.";输入Commend.exe -help或Commend.exe -h来查看帮助
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[ ])
{
for (size_t i = 0; i < argc; i++)
{
if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0)
{
printf("The Commend.exe's version is 1.0.");
}
else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
{
const char* help =
"--help, -h: Get list of available commands.\n"
"--version,-v:Get current version.\n";
printf("%s", help);
}
}
return 0;
}
注意到const char*的下方两行字符串是拆开写的, 但打印的时候是一起打印的,C语言标准中字符串常量会自动连接
如果两个字符串常量是由 " " 包围的文本直接相邻,它们会被编译器自动拼接成一个更长的字符串 编译器在处理时会将它们视作一个连续的字符串
执行结果
反思
main函数中if条件过长影响阅读,有点不简洁,可以用函数封装下专门判断
bool arg_is(const char* arg, const char* long_form, const char* short_form)
{
}
对于"--version"和"-v"有两种类型;对于"--help"和"-h"也有两种类型,因此函数可以返回两次比较后或的结果
优化代码
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool arg_is(const char* arg, const char* long_form, const char* short_form)
{
return strcmp(arg, long_form)==0 || strcmp(arg, short_form)==0;
}
int main(int argc, char* argv[])
{
for (size_t i = 0; i < argc; i++)
{
if (arg_is(argv[i],"--version","-v"))
{
printf("The Commend.exe's version is 1.0.");
}
else if (arg_is(argv[i], "--help", "-h"))
{
const char* help =
"--help, -h: Get list of available commands.\n"
"--version,-v:Get current version.\n";
printf("%s", help);
}
}
return 0;
}
3.实验2
编写命令行程序,输入Hello World!后将Hello World!视为一个参数在一行打印
由于有空格,Hello World会被默认解析为两个参数,可以通过加" "的方法来变成一个参数进行打印
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[ ])
{
for (size_t i = 0; i < argc; i++)
{
printf("%s\n", argv[i]);
}
return 0;
}
执行结果
4.实验3
输入Commend.exe --host ip地址来打印主机的ip地址(-host没有简写形式),使用arg_is函数来完成
注意:不能不修改arg_is函数就写成arg_is(argv[i],"--host",NULL)!这样传的就是空指针,会导致访问异常
可以利用短路运算的特点解决问题:是否有长/短名字?名字书写是否正确?
bool arg_is(const char* arg, const char* long_form, const char* short_form)
{
return (long_form && strcmp(arg, long_form)==0) || (short_form && strcmp(arg, short_form)==0);
}
无论参数只有一种写法还是有两种写法,该函数通吃
main函数修改为
int main(int argc, char* argv[])
{
for (size_t i = 0; i < argc; i++)
{
if (arg_is(argv[i],"--host",NULL))
{
printf("IP:%s",argv[i+1]);
}
}
return 0;
}
执行结果
看起来好像没问题
但是当只输入--host时,打印IP就会出问题
数组越界访问,需要修改代码
if (arg_is(argv[i],"--host",NULL))
{
printf("IP:%s",i+1 < argc ? argv[i+1] : "NULL");
}