200
任务描述
本关任务:文本匹配的时候经常会因为空格个数的不同而匹配失败,现在要求你编写程序对输入的字符串进行处理,去掉首尾的空格。
例如:输入的字符串是“ abcd ”,去掉首尾空格后字符串变为“abcd”。
相关知识
指针是 C 语言中的一个重要概念,也是 C 语言的一个重要特色。在 C 语言中,指针被广泛使用,它和数组、字符串、函数间数据的传递等有着密不可分的联系。可以说,没有掌握指针就没有掌握 C 语言的精华。
指针可以对内存中各种类型的数据进行快速、直接的处理,也可以为函数间的数据传递提供简洁、便利的方法。正确熟练地使用指针有利于编写高效的程序,但指针使用不当也容易导致严重错误。指针很灵活,也很危险。
定义指针变量
指针变量(简称指针)就是存放地址的变量。其声明形式与一般变量声明相比只是在变量名前多一个星号*
,接下来看两个例子。
例1:
int *p;
该例中声明了变量 p 为指向整型值的指针(即变量 p 中可以存放某个整型变量的地址)。这里的*
在声明语句中,是指针说明符,表示声明的变量是指针变量。
例2:
float *xPtr, *yPtr, f;
该例子中声明了两个指向浮点型值的指针 xPtr 和 yPtr 以及一个浮点型变量 f 。
指针的性质
① 指针可以赋值为 NULL 或某个地址。具有值 NULL 的指针不指向任何地址;
② 指针是具有特定属性的地址。光有地址只是知道数据存储在内存的某个位置,但怎么访问该位置的数据(即访问多少位,以什么方式访问)还需要指针类型来明确;
例如:使用 int 类型的指针访问其所指向的数据时,会一次性读取32位( int 类型的数据是32位),并使用整型数据的格式访问该数据。所以指针不仅仅是一个地址,还必须有特定的属性(类型)。
③ 数组名可以看成是一个特殊的地址,首先数组名是地址(数组的首地址),其次数组名有属性(数组元素的类型),所以可以把数组名赋值给同类型的指针变量。
例如:
char s[10] = "China";
char *sptr = s;
第二条语句赋值后 sptr 拥有和 s 同样的值,即数组的首地址,也就是存储字符‘C’的单元的地址。
④ 要访问指针所指向的单元可以使用间接引用运算符*
(不同于前面声明语句中的*
,这里的*
在表达式中,是运算符),*
也被称为复引用运算符,它返回其操作数(指针)所指向的对象;
例如:
char s[10] = "China";
char *sptr = s;
cout << *sptr;
将输出指针 sptr 所指的单元中存储的字符(因为 sptr 是 char 类型的指针),也就是输出字符‘C’。
⑤ 可以通过指针的复引用修改指针所指向的单元;
例如:
char s[10] = "China";
char *sptr = s;
*sptr = 'c';
上述代码会将该存储单元中大写字符的‘C’修改为小写字符的‘c’。
请注意前面代码的输出语句和下面的代码语句的区别:
char s[10] = "China";
char *sptr = s;
cout << sptr;
这条语句将输出字符串“China”。之前学习字符数组时应该知道,语句cout << s;
会输出数组 s 中存储的整个字符串,实际上 C++ 在使用 cout 输出 char 类型指针时,不是输出字符指针的值(地址),而是输出从该地址开始的字符串(逐个输出一个个字符,直到碰到 '\0' 为止)。所以cout << sptr;
和cout << s;
的作用一样,都是输出字符串“China”。
⑥ 访问一个字符串一般也是使用该字符串的首字符的地址;
⑦ 指针也可以参与算术运算。指针加上或减去一个整数 n,其运算结果是指向指针当前指向变量的后方或前方的第 n 个变量。
例如:之前 sptr 指向字符‘C’的存储单元,执行语句sptr++;
后 sptr 则指向字符‘h’的存储单元。如下语句:
```` while(*sptr != '\0') sptr++;
则可以使指针 sptr 指向该字符串后面的 '\0'。如果要输出字符串中的部分内容,也可以通过修改指针实现,如:
char s[10] = "China"; char *sptr = s; sptr++; cout << sptr;
上述代码执行语句`sptr++;`后,指针 sptr 指向了字符 'h' 的存储单元,此时`cout << sptr;`输出的是 sptr 指向的字符串,即“hina”。
⑧ 同类型的两个指针可以参与各种关系运算,其结果可以反映两指针所指向的地址之间的位置前后关系。
例如:
int a[10]; int *p = a, *q = &a[1]; if(p > q) cout << "p>q" << endl; else cout << "p<=q" << endl;
```
上述代码中指针 p 中存放的是 a 的值,也就是 a[0] 的地址,q 中存放的是 a[1] 的地址,而数组元素是按序连续存储的,所以 q 的值要比 p 的值大,程序输出p<=q
。
编程要求
在右侧编辑器中的Begin-End
之间补充代码,以实现去掉字符串(字符串由平台提供,且已在主函数中获取)首尾空格的功能。具体要求如下:
对于输入的字符串,去掉该字符串首尾的空格后输出;
字符串的存储使用一维字符数组,但本关要求使用指针操作。写完程序后,你也会发现使用指针实现会容易得多。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
为了方便显示空格,下面给出的测试输入使用下划线 '_' 表示空格。
测试输入:_____asd
预期输出:asd
测试输入:___a_b_c_d__
预期输出:a_b_c_d
开始你的任务吧,祝你成功!
#include <iostream>
using namespace std;
char * trim(char * str);
int main()
{
char s[1024]; // 定义存储字符串的一维字符数组
// 输入一行字符,可以包含空格
// 输入的字符串存入s中,最多读取个字符,后面自动加上'\0'
cin.getline(s,1024);
cout << trim(s) << endl; // 输出去掉首尾空格后的字符串
return 0;
}
// 函数trim:去掉字符串首尾空格
// 参数:str-字符指针,指向输入的字符串
// 返回值:字符指针,指向去掉首尾空格后的字符串(首地址)
// 提示:可以直接在字符串str中操作
char * trim(char * str)
{
// 请在此添加代码,实现函数trim
/********** Begin *********/
char *p=str;
while(*p!='\0'){
p++;
}
p--;
while(p>str&&*p==' '){
*p='\0';
p--;
}
while(*str==' '){
str++;
}
return str;
/********** End **********/
}
100
任务描述
本关任务:使用指针实现两个整数值的交换。
相关知识
用指针传递参数
C 和 C++ 函数调用的参数传递方式有两种:传值和传引用。
传值只是值的传递,被调用函数则无法修改实在参数的值;
传引用则是实参和形参共享实在参数的存储单元,所以被调用函数可以通过修改形参来修改实参的值。
如果采用传值的方式传递指针值,可以实现类似于传引用的效果。
例如:
#include <iostream>
using namespace std;
// 函数inc:将p指向的整数值加
// 参数:p-int类型指针,指向要加的整数
void inc(int * p)
{
(*p)++; // *p 访问 p 指向的单元,++ 将该单元的数据加
// 注意不能是 *p++, 因为 * 和 ++ 优先级相同,且右结合,这种写法修改的是 p 的值,而不是 *p 的值
}
int main()
{
int a = 10;
inc(&a); // 调用 inc 函数,修改 a 的值(传递的是 a 的地址)
cout << a << endl; // 输出 a 的值
return 0;
}
上述程序的输出为11,其中被调用函数 inc 只修改了 main 函数中的局部变量 a 的值,但并没有修改实参的值(实参是&a
,即 a 的地址依然没变)。
编程要求
在右侧编辑器中的Begin-End
之间补充代码,实现使用指针将两个整数(数据由平台提供,且已在主函数中获取)值交换的功能。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:1 2
预期输出:2 1
测试输入:123 678
预期输出:678 123
开始你的任务吧,祝你成功!
#include <iostream>
using namespace std;
void pswap(int * p, int *q);
int main()
{
int a, b;
cin >> a >> b; // 输入两个整数
pswap(&a,&b); // 调用pswap函数,交换a、b的值
cout << a << " " << b << endl; // 输出a、b的值
return 0;
}
//函数pswap:交换指针p和q指向的单元中的整数值
//参数:p,q-int类型指针,指向要交换的整数
void pswap(int * p, int *q)
{
// 请在此添加代码,实现函数pswap
/********** Begin *********/
int t;
t=*p;
*p=*q;
*q=t;
/********** End **********/
}
400
任务描述
本关任务:在一串隐藏着一个或多个数值的字符中,选出字符串中的所有数字字符,并将选出的数字字符重新组成新字符串。如果在第一个数字字符之前有负号,则保留该负号,有多个负号时只保留一个。
例如:输入的字符串为“a-1-2-4sd5 s6”,抽取数字后得到的新字符串为“-12456”。
相关知识
完成本关需要具备的知识介绍请参见第一、二关卡。
编程要求
在右侧编辑器中的Begin-End
之间补充代码,选出字符串(数据由平台提供,已且在主函数中获取)中的所有数字字符并组成新的字符串输出。要求如果在第一个数字字符之前有负号,则保留该负号,有多个负号时也只保留一个。
提示
如果有字符指针 p 和 q,则下面的程序可以实现:当 q 指向的字符是数字时,将 q 指向的数字拷贝到 p 指向的存储单元:
if(*q >= '0' && *q <= '9')
{
*p = *q;
}
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:1 s23df53dcas12sd-121sd
预期输出:1235312121
测试输入:a-1-2-3sd45 j67sd
预期输出:-1234567
开始你的任务吧,祝你成功!
#include <iostream>
using namespace std;
void extractNum(char * str);
int main()
{
char s[1024];
cin.getline(s,1024); // 输入一行字符
extractNum(s); // 调用extractNum函数,选出数字
cout<<s<<endl; // 输出选出的数字
return 0;
}
// 函数extractNum:选出str指向的字符串中的数字,并写回str
// 参数:str-指向字符串
void extractNum(char * str)
{
// 请在此添加代码,实现函数extractNum
/********** Begin *********/
char *p=str,*q=str;
int isPrime=1;
while(*p!='\0'){
if(*p=='-'&& isPrime){
isPrime=0;
*q++=*p++;
}else if(*p>='0'&&*p<='9'){
isPrime=0;
*q++=*p++;
}else{
p++;
}
}
*q='\0';
/********** End **********/
}
200
任务描述
本关任务:将一个字符串中的所有小写字母变成对应的大写字母,其它字母不变。
例如:对字符串“abc12! ef”执行函数后输出结果为“ABC12! EF”。
相关知识
完成本关需要具备的知识介绍请参见第一、二关卡。
编程要求
在右侧编辑器中的Begin-End
之间补充代码,实现将字符串(数据由平台提供,且已在主函数中获取)中的所有小写字母变成对应大写字母,其它字母不变的功能。
提示
在 ASCII 码表中,大写字母‘A’到‘Z’是连续编码的,小写字母‘a’到‘z’也是连续编码的。也就是说‘A’和‘a’的 ASCII 码的差与‘Z’和‘z’的 ASCII 码的差是一样的。
所以如果字符变量 ch 中存放的是小写字母,则下面的语句可以将其变成对应的大写字母:
ch = ch + 'A'-'a';
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:1q2w3ASD45sx~1
预期输出:1Q2W3ASD45SX~1
测试输入:as 12xfASA90[]kl{}
预期输出:AS 12XFASA90[]KL{}
开始你的任务吧,祝你成功!
#include <iostream>
using namespace std;
void toUp(char * str);
int main()
{
char s[1024];
cin.getline(s,1024); // 输入一行字符
toUp(s); // 调用toUp函数,转换成大写字母
cout<<s<<endl; // 输出变更后的新字符串
return 0;
}
// 函数toUp:将str指向的字符串中的小写字母变成对应的大写字母
// 参数:str-指向字符串
void toUp(char * str)
{
// 请在此添加代码,实现函数toUp
/********** Begin *********/
char *p=str,*q=str;
while(*p!='\0'){
if(*p>='a'&&*p<'z'){
*q++=*p++-32;
}else{
*q++=*p++;
}
}
*q='\0';
/********** End **********/
}
500
任务描述
本关任务:计算一个字符串(子串)在另一个字符串(长串)中出现的次数。
相关知识
字符串操作函数
C 和 C++ 提供了一系列操作字符串的函数,要使用这些函数只要在代码的头文件部分包含 string.h 即可。
常用的字符串处理函数见下表:
函数原型 | 函数功能 |
---|---|
char * strcpy(char *dest,const char *src) |
将字符串 src 复制到 dest |
char * strcat(char *dest,const char *src) |
将字符串 src 添加到 dest 末尾 |
char * strchr(const char *s,int c) |
检索并返回字符 c 在字符串 s 中第一次出现的位置 |
int strcmp(const char *s1,const char *s2) |
比较字符串 s1 与 s2 的大小,若 s1 串大于 s2 串则返回一个大于 0 的值;若 s1 串等于 s2 串则返回值为 0;若 s1 串小于 s2 串则返回一个小于 0 的值。 |
size_t strlen(const char *s) |
返回字符串 s 的长度 |
char * strncat(char *dest,const char *src,size_t n) |
将字符串 src 中最多 n 个字符复制到字符串 dest 中 |
int strncmp(const char *s1,const char *s2,size_t n) |
比较字符串 s1 与 s2 中前 n 个字符 |
char * strncpy(char *dest,const char *src,zise_t n) |
复制 src 中的前 n 个字符到 dest 中 |
char * strstr(const char *s1,const char *s2) |
扫描字符串 s1,并返回第一次出现 s2 的位置 |
char * strtok(char *s1,const char *s2) |
检索字符串 s1,该字符串 s1 是由字符串 s2 中定义的定界符所分隔 |
strstr 函数
在一个长串中查找子串可以使用strstr
函数,该函数的函数原型为:
char* strstr(const char* s1, const char* s2);
该函数从 s1 所指字符串中第一个字符起,顺序向后查找出与 s2 所指字符串相同的子串,若查找成功则返回该子串首次出现的首地址,否则返回 NULL。
例如:
char *a="abcdeabcde";
char *b="bcd";
cout<<strstr(a,b)<<endl;
该程序输出结果为“bcdeabcde”,因为strstr(a, b)
的返回值为“bcd”在“abcdeabcde”中第一次出现的首地址,所以用 cout 输出时,从该位置的字符开始,逐个输出直到 '\0',即字符串“bcdeabcde”。
当然,查找子串时,也可以从长串的某个位置开始。
例如:
char *a="abcdeabcde";
char *b="bcd";
cout<<strstr(a+4,b)<<endl;
该程序的输出为“bcde”。因为a+4
得到一个新地址,即 a 指向的字符串中第一个字符‘e’的地址,从该位置开始查找 b 指向的字符串‘bcd’,得到从字符‘e’开始的第一个“bcd”出现的地址,然后用 cout 输出该地址开始的字符串,即“bcde”。
strlen 函数
另外,下次从什么地方开始查找子串?应该是上次找到子串的开始位置加上子串的长度。其中,函数strlen
可以计算字符串的长度,其函数原型为:
int strlen(const char *s);
函数 strlen 只有一个参数 s,它是一个字符指针,代表了一个字符串,函数计算 s 指向字符串的长度并返回。
例如:
char *a="x";
char *b="Hello world!";
cout<<strlen(a)<<endl; // 输出 1
cout<<strlen(b)<<endl; // 输出 12
编程要求
在右侧编辑器中的Begin-End
之间补充代码,计算一个字符串(子串)在另一个字符串(长串)中出现的次数。
提示
一个子串在另一个长串中出现的次数是指长串中可以同时截取出多少个子串。例如:子串 "aaa" 在 "aaaaaaa" 中出现的次数为 2 次。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入: aaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
预期输出: 7
测试输入: ab
aaaaabbbbbabcdefg
预期输出: 2
开始你的任务吧,祝你成功!
自己打败自己是最可悲的失败,自己战胜自己是最可贵的胜利。
如果你觉得这一关的内容对你有帮助,请你在下面点赞。
// 包含字符串函数库
#include <string.h>
#include <iostream>
using namespace std;
int frequency(char * substr, char * str);
int main()
{
char sub[128],str[1024];
cin.getline(sub,128); // 输入子串
cin.getline(str,1024); // 输入长串
int n = frequency(sub,str); // 调用frequency函数,计算子串在长串中出现的次数
cout<<n<<endl; // 输出次数
return 0;
}
// 函数frequency:计算子串在长串中出现的次数
// 参数:substr-指向子串,str-指向长串
// 返回值:出现的次数
int frequency(char * substr, char * str)
{
// 请在此添加代码,实现函数frequency
/********** Begin *********/
char *p=substr,*q=str;
int n=0;
while(q=strstr(q,p)){
n++;
q=strstr(q,p)+strlen(p);
}
return n;
/********** End **********/
}
500
任务描述
本关任务:实现字符串的部分复制。
相关知识
完成本关需要具备的知识介绍请参见第五关卡。
编程要求
在右侧编辑器中的Begin-End
之间补充代码,实现字符串的部分复制。
提示
函数 strmncpy 的原型为:
void strmncpy(char *s, int m, int n, char *t);
参数 s 指向源字符串,t 指向字符串复制的目标单元,函数功能为将 s 指向字符串从第 m 个(从0开始编号)字符开始的连续 n 个字符复制到 t 指向的存储单元;
如果第 m 个字符后面的字符数不足 n 个,则复制到 '\0'为止;
如果 s 的长度不到 m,则复制空串。
例如:
char *s = "abcdefghijklmn";
char t[20];
strmncpy(s,4,6,t);
cout << t << endl;
输出结果为:efghij
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:
abcdefghjkksdsd
5 7
预期输出:fghjkks
测试输入:
asdftyuioplkm
3 9
预期输出:ftyuioplk
开始你的任务吧,祝你成功!
#include <iostream>
using namespace std;
void strmncpy(char *s, int m, int n, char *t);
int main()
{
char s[128],t[128];
int m,n;
cin>>s; // 输入源串
cin>>m>>n; // 输入m和n
strmncpy(s, m, n, t); // 字符串复制
cout << t <<endl; // 输出复制结果
return 0;
}
// 函数strmncpy:字符串的部分复制,将s指向字符串从第m个字符开始的n个字符复制的t中
// 参数:s-指向源字符串,t-指向目标字符串,m-起始位置,n-字符个数
// 返回值:无
void strmncpy(char *s, int m, int n, char *t)
{
// 请在此添加代码,实现函数strmncpy
/********** Begin *********/
s+=m;
while(*s!='\0'&&n!=0){
*t++=*s++;
n--;
}
*t='\0';
/********** End **********/
}
单例模式是java中最简单的设计模式之一,属于创建式模式,提供了一种创建对象的最佳方式。具体而言,单例模式涉及到一个具体的类,这个类可以确保只有单个对象被创建。它包含一个访问其唯一对象的方法,供外部直接调用,而不需要创建这个类的示例。简而言之,可以不再new一个他的实例,而是直接调用方法。
文章浏览阅读2.7k次。增量式PI的程序百度一搜由算法可以看出,主要是误差参与运算,控制量可以理解为误差的累计和消除过程,比如第一次调节有误差1,第二次调节有误差2,误差2的出现说明第一次调节没有调整到给定值,控制量在第二次会改变,这样继续调节下去,调整到给定值时候,理论上是0了。比例积分系数和控制量的关系比例可认为是快速到达给定值积分可认为是消除稳态误差一般的系统,PI就够用了基本思路1初始化给定值,或是外部给予2实时采样被控对象3采样值与外部给予比较,并进行算法处理,得到控制量4由控_通过pi控制算法得到的增量怎么转化为pwm的频率
Ansible 提供了多种方式来定义和管理主机列表,除了默认的文件之外,您还可以使用自定义主机列表。这提供了更大的灵活性,允许您根据需要从不同来源获取主机信息。
文章浏览阅读1.8k次,点赞6次,收藏36次。堆栈(stack)的基本概念堆栈是一种特殊的线性表,堆栈的数据元素及数据元素之间的逻辑关系和线性表完全相同,其差别是:线性表允许在任意位置插入和删除数据元素操作,而堆栈只允许在固定一端进行插入和删除数据元素操作。 堆栈中允许进行插入和删除数据元素操作的一端称为栈顶,另一端称为栈底。栈顶的当前位置是动态的,用于标记栈顶当前位置的变量称为栈顶指示器(或栈顶指针)。 堆栈的插入操作通常称为进栈或入栈,每次进栈的数据元素都放在原当前栈顶元素之前而成为新的栈顶元素。堆栈的删除操作通常称为出栈或退栈,每次出栈的_c语言堆栈
文章浏览阅读1.6k次。敏感词过滤是随着互联网社区发展一起发展起来的一种阻止网络犯罪和网络暴力的技术手段,通过对可能存在犯罪或网络暴力可能的关键词进行有针对性的筛查和屏蔽,很多时候我们能够防患于未然,把后果严重的犯罪行为扼杀于萌芽之中。_违规关键词过滤api
文章浏览阅读9.1k次,点赞2次,收藏42次。———————10月14日更—————————- 发现在goal-topo.cc中,由于Node#14被放在初始位置为0的地方,然后它会收到来自AP1和AP2的STA的OLSR消息(距离他们太近了吧)。 然而与goal-topo-trad.cc不同,goal-topo-trad.cc中Node#14可以在很远就跟自己的AP3通信,吞吐量比较稳定。而goal-topo.cc在开始的很长时间内并_ns3计算吞吐量
文章浏览阅读1k次。十二、播放模型动画1.这里我们要做的是第一次点击中心按钮播放打开车门动画,第二次点击中心按钮关闭车门动画。2.新建一个脚本,命名为“AnimationManager.cs”。(代码如下)using System.Collections.Generic;using UnityEngine;/// <summary>动画管理</summary>public class AnimationManager : MonoBehaviour{ /// <s._arfoundation 关闭动画位移计算
文章浏览阅读220次。Idea 运行spring项目 出现的bugbug 1错误信息:Cannot start compilation: the output path is not specified for module “02_primary”.Specify the output path in the Project Structure dialog.解决办法:..._idea spring代理对象出bug
文章浏览阅读1k次,点赞2次,收藏6次。Node,就是节点,在整体结构中,就是黄色那一块,红色也算个人理解,在实际中,Node可以说是我们的UI页面上的每一个节点了,比如按钮、标签之类的控件,而这些控件,大多都是有一些通用属性的,以下简单介绍一下。_javafx教程-ui控件
文章浏览阅读136次。此笔记由个人整理塞上苍鹰_fly课程来自:正点原子_手把手教你学Linux一、文件系统结构g根目录:Linux下“/”就是根目录!所有的目录都是由根目录衍生出来的。/bin存放二进制可执行文件,这些命令在单用户模式下也能够使用。可以被root和一般的账号使用。/bootUbuntu内核和启动文件,比如vmlinuz-xxx。gurb引导装载程序。/dev设备驱动文件/etc存放一些系统配置文件,比如用户账号和密码文件,各种服务的起始地址。._嵌入式linux使用ubuntu文件系统
文章浏览阅读2.1k次。此问题已向微软公司反馈,仅供学习参考这是微软内核的一个Bug.发生在内核函数 MmEnumerateAddressSpaceAndReferenceImages 和 MiCreateEnclave之间,如果时机不当会造成这两个函数之间死锁,而且还是一个pushlock死锁问题,十分罕见,这也是导致系统开机黑屏,系统突然卡死的元凶之一。Win10被骂了很久了,这次真的被我遇上了,系统无缘无故卡死_win10黑屏卡死原因分析--罕见的内核pushlock死锁问题
文章浏览阅读112次。巧用批处理解决IE不支持javascript等问题rem=====批处理开始========regsvr32actxprxy.dllregsvr32shdocvw.dllRegsvr32URLMON.DLLRegsvr32actxprxy.dllRegsvr32shdocvw.dllregsvr32oleaut32.dllrundll32.exeadvpack.dll/DelNo..._ie不支持javasript批处理