C语言习题四
题目1
题目:请编写一个函数,它在字符串中进行搜索,查找所有在一个给定字符集合中出现的字符。这个函数的原型应该如下:
char *find_char(char const *source, char const *chars);
它的基本想法是查找source字符串匹配chars字符串中任何字符的第一个字符,函数然后返回一个指向source中国第一个匹配所找到的位置的指针。如果source中的所有字符均不匹配chars中的任何字符,函数就返回一个NULL指针。如果任何一个参数为NULL,或任何一个参数所指向的字符串为空,函数也返回一个NULL指针。
举个例子,假定source指向ABCDEF。如果chars指向XYZ,JURY或者QQQQ,函数就返回一个NULL指针。如果chars指向XRCQEF,函数就返回一个指向source中C字符的指针。参数所指向的字符串时绝不会被修改的。
碰巧,C函数库中存在一个名叫strpbrk 的函数,它的功能几乎和你要编写的函数一模一样。但这个程序的目的是让你自己练习操纵指针,所以:
a:你不应该使用任何用于操纵字符串的库函数(如strcpy,strcmp,index等);
b:函数中的任何地方都不应该使用下标引用。
思路:双循环遍历源串和目标串,依次进行比较,判断是否相等。
代码如下:
#include<stdio.h> #include<string.h> char *find_char(char const *source, char const *chars) { char *tempSource = source; /* ** 参数检查 */ if (source == NULL || chars == NULL) { return NULL; } if (*source == '\0' || *chars=='\0') { return NULL; } //遍历目标串 while (*chars++ != '\0' ) { tempSource = source; //遍历原串 while (*tempSource++ != '\0') { if (*tempSource == *chars) { return tempSource; } } } return NULL; } int main() { char *source = "ABCDEF"; char *chars = "XRCQEF"; //调用系统自带的库函数 if (strpbrk(source, chars) == NULL) { printf("并未查找到匹配字符\n"); } else { printf("%c\n",*(strpbrk(source,chars))); } //调用自定义函数 if (find_char(source, chars) == NULL) { printf("并未查找到匹配字符\n"); } else { printf("%c\n", *(find_char(source, chars))); } return 0; }
题目2
题目:请编写一个函数,删除一个字符串的一部分。函数的原型如下:
int del_substr(char *str, char const *substr)
函数首选应该判断substr是否出现在str中。如果它并未出现,函数就返回0;如果出现,函数应该把str中位于该子串后面的所有字符复制到该子串的位置,从而删除这个子串,函数就返回1.如果substr多次出现在str中,函数只删除第一次出现的子串。函数的第2个参数绝不会被修改。
举个例子,假定str指向ABCDEFG。如果substr 指向FGH,CDF或XABC,函数应该返回0,str未作任何修改。但如果substr指向CDE,函数就把str修改为指向ABFG,方法是把F、G和结尾的NUL字节复制到C 的位置,然后函数返回1。不论出现什么情况,函数的第2个参数都不应该被修改。
a:你不应该使用任何用于操纵字符串的库函数(如strcpy,strcmp,index等);
b:函数中的任何地方都不应该使用下标引用。
思路:先确定源串中有没有子串,如果有子串,再利用指针删除。
代码如下:
#include<stdio.h> int del_substr(char *str, char const *substr) { char *temp_substr = substr; //参数检查 if (str == NULL || temp_substr == NULL) { return NULL; } if (*str == '\0' || *temp_substr == '\0') { return NULL; } while (*str++ != '\0') { while (*temp_substr++ != '\0') //双层循环遍历 { //源指针和目标指针同时变化,如果发现源指针值和目标指针值不一致,则让目标指针回滚。 if (*temp_substr != *str && *temp_substr!='\0') { temp_substr = substr; } break; } if (*temp_substr == '\0') //表示源串中有子串 { //当源串中有子串时,利用当前源指针和目标指针的位置,删除源串中的子串 while (*--str == *--temp_substr) { char *temp_str = str; char *tempTwo_str = str; while (*temp_str++ !='\0') { *tempTwo_str = *temp_str; tempTwo_str++; } *tempTwo_str = '\0'; } return 1; } } return 0; } int main() { char str[] = "CCDEFG"; char *substr = "CDE"; char *dest_str = str; //为了打印,故定义一个字符串指针 if (del_substr(str, substr)) { while (*dest_str !='\0') { printf("%c", *dest_str); dest_str++; } } return 0; }
题目3
题目:编写函数reverse_string,它的原型如下:
void reverse_string(char *string);
函数把参数字符串中的额字符反向排列。请使用指针而不是数组下标,不要使用任何C函数库中的用于操纵字符串中的函数。提示:不需要声明一个局部数组来临时存储参数字符串。
思路:刚开始我是采用移动字符串的方法,但是思路太复杂,找不到结束循环的条件。参照网上的思路,才发现交换真的很简单,于是使用交换修改了程序。
代码如下:
#include<stdio.h> void reverse_string(char *string) { int len = 0; char *p; //头指针 char *q; //尾指针 char temp; p = string; while (*p!='\0') { len++; p++; } q = p - 1; p = string; for (int i = 0; i <= (len/2); i++) //交换字符 { temp = *p; *p = *q; *q = temp; p++; q--; } } int main() { char str[] = "ABCDEFGHIJK"; reverse_string(str); printf("%s",str); return 0; }