113.【C语言】编写命令行程序(2)

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");
		}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值