前言

做个小测试


正文

大致就是利用main函数的参数,去实现拆分参数,不使用原生支持的string功能自己写一个类似的。

filename.exe id:1 pass:123456 contry:china

不管第一个默认的文件名参数,从后面开始,挨个拆出:后面的值

1
2
3
int searchChar(){

}

一开始想着是不是要传递:的位置,这样直接截取:后面的就行了。

但是这样又很奇怪,因为只做了返回位置,截取还要另外实现。
那好像又要两个自定义函数了,或者在main函数里实现,都是挺麻烦的。

直接返回ch[] 也不对劲,因为数组是要提前声明大小的……
回头一想,数组的底层也是指针,那就返回char*类型的应该也凑合:

1
2
3
char* searchChar(){

}

然后就是参数,肯定要有俩,一个原字符串,一个要查询被丢弃的字符串,然后这俩肯定不用修改了,就const限定常量

1
2
3
char* searchChar(const char *str, const char *findstr){

}

然后进一步堆屎山:

1
2
3
4
5
6
7
8
9
char* serachChar(const char *str, const char *findstr){
int *ch;
for (int i = 0; str[i]; i++){
if (str[i] != findstr[i]){
ch += str[i];
}
}
return ch;
}

这里肯定是不对的,因为指针没有初始化。。编译不通过。你也不知道到底该分配多少个内存。
那就不能用额外声明的指针返回,直接返回str[]从什么位置开始返回好像会更好
但是这样的话就要判断什么时候返回,返回的位置怎么计算合适。

1
2
3
4
5
6
7
8
9
10
11
12
char* serachChar(const char *str, const char *findstr){
int x = 0;
for (int i = 0; str[i]; i++){
if (str[i] == findstr[i]){
x++;
}
else{
return (char*)&str[x + (i-x)];
}
}
return nullptr;
}

试了大半天,测了几个样例,能得到正常的值了

  1. 首先需要一个x,这个x是累计str和findstr有几个相同的元素
  2. 考虑到for循环里面else就应能返回一个正确值了,那么最外层必须要有一个返回值的前提就返回一个空指针
  3. for循环使用str[i]是因为字符串以0结尾,效果一样,就是到头了就表示false了。
  4. return (char*)&str[x+(i-x)]是因为假设x=2,那么下一次i=3的时候其实就可以返回后面的地址了。表达式写成x+(i-x),其实就是2+1…等会我直接用i好像就行了。
1
2
3
4
5
6
7
8
9
10
11
12
char* serachChar(const char *str, const char *findstr){
int x = 0;
for (int i = 0; str[i]; i++){
if (str[i] == findstr[i]){
x++;
}
else{
return (char*)&str[i];
}
}
return nullptr;
}

return (char*)&str[i]; i就行了,不用整表达式了。

然后就是用命令行的方式去实现。不过要在main函数里先赋值

1
2
3
4
5
const char *idN = "id:";
const char *passN = "pass:";
const char *countryN = "country:";
char *id{}, *pass{}, *country{};

先定义需要的变量。
然后for循环argv使用自定义函数赋值

1
2
3
4
5
6
7
8
9
10
11
for (int i = 1; argv[i]; i++){
if (id == nullptr){
id = serachChar(argv[i], idN);
}
if (pass == nullptr){
pass = serachChar(argv[i], passN);
}
if (country == nullptr){
country = serachChar(argv[i], countryN);
}
}

i=1是因为0是程序名,不需要进行判断,直接忽略就行,我们要截取的是后面的参数
id,pass,country默认都是空指针,当他们==nullptr的时候,就进行serachChar。
不过这样的话当三个参数时,argv[1]走了三遍,[2]走了两遍,[3]走了一遍,但if都是重复判断了,又有点麻烦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (int i = 1; argv[i]; i++){
if (id == nullptr){
id = serachChar(argv[i], idN);
if (id != nullptr) continue;
}
if (pass == nullptr){
pass = serachChar(argv[i], passN);
if (pass != nullptr) continue;
}
if (country == nullptr){
country = serachChar(argv[i], countryN);
if (country != nullptr) continue;
}
}

参考了视频,在赋值后,判断不为空就continue也不失为一种办法,目前没想到啥好主意就先用了。

1
2
3
std::cout << id << std::endl;
std::cout << pass << std::endl;
std::cout << country << std::endl;

输出就不用干啥了,然后就编译一下,发现不通过,这个程序没用明面上的输入就输出值好像不允许。
视频是通过(int)强转三个指针然后相乘,因为不为空都是有值的存在,故此if也能通过

1
2
3
4
5
if ((int)id * (int)pass * (int)country){
std::cout << id << std::endl;
std::cout << pass << std::endl;
std::cout << country << std::endl;
}

跑到终端尝试:
结果是正常的,然后再看看有啥能优化的:

1
2
3
4
5
6
7
8
char* serachChar(const char *str, const char *findstr){
for (int i = 0; str[i]; i++){
if (str[i] != findstr[i]){
return (char*)&str[i];
}
}
return nullptr;
}

其实也挺好整的,因为我们之前实现比较相同部分,再去返回相同之后的部分,那么换算过来直接返回当两个字符串不相等的位置就可以了。

重新编译之后运行也是正确的:

然后就可以告一段落了,自己写一个功能其实会小有成就感。


结语

大半夜想了半天,看了眼视频发现路数差不多。