C语言复习-字符串与指针
例一:
【字符串处理 去除C代码中的注释】
C/C++代码中有两种注释,/* */和//。编译器编译预处理时会先移除注释。就是把/*和*/之间的部分去掉,把//以及之后的部分删掉。这里约定,如果出现了/* AAAA /* BBBB */的情况,也就是/**/中出现了/*,那么第二个/*是不当作注释起始的。编写函数void removeComment(char *str)。
分析:对于字符串”int c=4,/*c累计量*/ a=3;/*变量*/ // a初值为3 ”先用strstr函数在str中确认”/*” 是否出现过,是则再确认”*/” 是否出现过,是则把str中自”*/”出现位置后2个字符起始的字符串复制到str中”/*”开始的位置,覆盖掉注释部分。循环查找直到找不到”/*”为止;再用strstr在str中确认”//” 是否出现过,是则把出现”//”的位置上置为’\0’。
#include <stdio.h> #include <string.h> void removeComment(char *str) { char *p=str, *q; while ((p=strstr(p, "/*")) != NULL) { q=strstr(p, "*/"); if (q != NULL) strcpy(p, q+2); } p = strstr(str, "//"); if (p !=NULL) *p = '\0'; } void main( ) { char s[]="int c=4, /*c累计量*/ a=3; /*变量*/ // a初值为3"; removeComment(s); printf("%s\n", s); }
运行结果:
int c=4, a=3
本体关键在于复习两个重要函数strstr和strcpy
strstr:给定字符数组指针和待查找的字符串,strstr函数将从当前指针开始查找直到第一个遇见待查找字符串,并返回其地址,若未找到则返回NULL。
strcpy: 给定两个字符指针p和q,将把q所指向的内容复制到p所指向的内容。
例二:
【字符串处理 去除字符串中非字母字符 】
编写函数 void FilterNonChar (char *str)
对于字符串
str= ”int c=4,/*c累计量*/ a=3;/*变量*/ // a为3 ”
最后结果应该是:
str= ”intccaa”
分析:
设循环变量k从0到strlen(str)循环,逐个字符判断str[k]是否为字符,是留下,向前移动位置,不是忽略。
for(k=0; k<strlen(str); k++) if (str[k]>=‘a’&&str[k]<=‘z’ || str[k]>=‘A’&&str[k]<=‘Z’) // if (isalpha(str[k])) // 此函数隶属于 ctype.h
答案:
#include <stdio.h> #include <string.h> #include <ctype.h> void FilterNonAlpha(char *str) { int k, n=0; for(k=0; k<strlen(str); k++) if (str[k]>='a'&&str[k]<='z' || str[k]>='A'&&str[k]<='Z') // if (isalpha(str[k])) str[n++]=str[k]; str[n] = '\0'; /* 设置新的字符串尾 } void main( ) { char s[]="int c=4,/*c累计量*/ a=3;/*变量*/ // a初值为3"; FilterNonAlpha(s); printf("%s\n", s); }
本题在于复习字符串扫描时的步进逻辑,核心语句是
str[n++]=str[k];
例三:
3【字符串处理 翻译机】
把一个句子中的单词的顺序倒过来。
输入:
theatre the to went I week Last
输出:
Last week I went to the theatre
分析:
如果能循环找出句子中的每一个空格,置为\0,设置一个指针数组,每一个指针指向每一个单词的开始处,逆向打印指针数组中的每一个单词,即可实现翻译机“把一个句子中的单词的顺序倒过来”的要求。
#include <stdio.h> void main() { char s[1000], *p[100]; int k=0,n=0; gets(s); p[0] = s; for(;s[k]; k++) // 中间是条件表达式,s[k]碰上末尾的'\0'会停下 if (s[k]==' ') { s[k]='\0'; n++; p[n]=&s[k+1]; } for(k=n; k>=0; k--) // 逆序打印 printf("%s ", p[k]); }
这题需要注意的知识点包括:
- 指针数组的使用
- 指针数组的声明 char *p[100]
- 对指针数组中的元素赋值 p[n] = &s[k+1] p[0] = s
- gets()函数的使用
- for循环的特殊写法
例四:
【字符串处理 句子单词匹配】
从键盘上输入两个英文句子,输出他们相同单词的个数(句子最少包含一个单词,不包含标点符号,所有字母均为小写,单词与单词之间用’&’符号隔开)。
例如:输入
i&am&a&student
today&is&monday
输出 0
输入
now&is&tow&to&two
tow&classes
输出 1
分析:
如果能循环找出句子中的每一个&,置为\0,设置一个指针数组,每一个指针指向每一个单词的开始处,那么句子单词匹配问题就变成了循环比较两个指针数组中单词是否相同并计数。
#include <stdio.h> #include <string.h> void main() { char s1[1000],s2[1000],*p1[100],*p2[100]; int k,m,n1=0,n2=0, same=0; gets(s1); gets(s2); p1[0] = s1; p2[0] = s2; for(k=0;s1[k]; k++) if (s1[k]=='&') { s1[k]='\0'; n1++; p1[n1]=&s1[k+1]; } for(k=0;s2[k]; k++) if (s2[k]=='&') { s2[k]='\0'; n2++; p2[n2]=&s2[k+1]; } for(k=0; k<=n1; k++) for(m=0; m<=n2; m++) if (!strcmp(p1[k],p2[m])) same++; printf("%d\n", same); }
本题注意几点:
- 输入统统使用字符数组和gets()函数来接收,这样做有几点好处,一来简化scanf写法,二来字符数组可变,相比于静态字符串更加灵活。
- 每个单词的存储使用指针数组完成,包括如下几步1.创建适合大小的指针数组,可以暂时不初始化2.遍历特定字符数组时对指针数组中的元素采用取地址赋值。
来源:https://www.cnblogs.com/BertramRay/p/12327529.html