C语言学习笔记9
程序员文章站
2022-07-15 08:46:59
...
字符串练习题
//1.查找一个字符在另外一个字符串中第一次出现的下标
//2.查找一个字符在另外一个字符串中第一次出现的地址
//3.查找一个字符串在另外一个字符串中第一次出现的地址 abcccccde ccd
//4.统计一个字符串中单词的个数(单词与单词之间是空格分割)“a abc make 89 12 a ma make 12 abc 89”
//5.将一个字符串插入到另一个字符串中 “abcd” “12345” 3
//(将第二个字符串插入到第一个字符串第三位的前面也就是ab12345cd)
#include <stdio.h>
#include <string.h>
int T1(char* str, char a);
char* T2(char* str, char a);
char* T3(char* str1, char* str2);
int T4(char* str1);
//char* T5(char* str1, char* str2, char* str);
//插入要在原有的基础上去做,不要开辟更大的空间
void T5(char* str1, char* str2, int n);
int main()
{
printf("T1----------------------\n");
printf("%d\n", T1("abc", 'c'));
printf("%d\n\n", T1("abc", 'e'));
printf("T2----------------------\n");
//(检验地址可以间接引用,看看是不是这个地址上的内容就可以了)
printf("%c\n\n", *T2("abc", 'c'));
printf("T3----------------------\n");
//(只要确认前三个内容正确即可)
printf("%s\n\n", T3("abcccccde", "ccd"));
printf("T4----------------------\n");
printf("%d\n\n", T4("a abc make 89 12 a ma make 12 abc 89"));
printf("T5----------------------\n");
//printf("%s\n\n",T5("abcd","12345",3));
//str1的数组长度不够大
char str[20] = "abcd";
T5(str, "12345", 3);
printf("%s\n\n", str);
//输出结果是ab12345
return 0;
}
int T1(char* str, char a)
{
int Mark = 0;
while (*str != '\0')
{
if (*str == a)
{
return Mark;
}
str++;
Mark++;
}
return -1;
}
char* T2(char* str, char a)
{
while (*str != '\0')
{
if (*str == a)
{
return str;
}
str++;
}
return NULL;
}
char* T3(char* str1, char* str2)
{
while (*str1 != '0')
{
if (0 == strncmp(str1, str2, strlen(str2)))
{
return str1;
}
str1++;//char* 字符指针数据类型,str1++则表示指向位置偏移
}
return NULL;
}
int T4(char* str1)
{
int count = 0;
while (*str1 != '\0')
{
if (*str1 == ' ') //注意=和==的区别!
{
count++;
}
str1++;
}
return count+1;
}//注意:本程序只能计算每个单词之间空一个格的单词个数,如果每个单词间空多个或者全是空格没有单词则不成立了
void T5(char* str1, char* str2, int n)
//思路:
//先找到第三位的位置,两种方式,①先遍历字符串找到第三位,②直接进行字符串数组偏移到第三位
//然后再将第三位之后的字符串偏移插入字符串字数的数量,需要注意的是要从后往前一位位移动,如果从前往后以后,一旦第三位之后的字符串字数数量大于要插入的字符串字数数量,那么原来的字符串就会有被覆盖的情况发生。
{
char* p1 = str1 + n - 1;//找到第三位前的位置:首地址+3-1
char* p2 = str1 + strlen(str1);//找到'\0'的位置,还有遍历的方法但是比较麻烦
//strlen计算字符串长度时候不计算’\0’在内,-1的原因是str1是第一个字符的地址,strlen把第一个重复计入了
//①while (p1 < p2) //要插入的位置在\0的前面
//但此时c没有挪过去,当p1和p2都指向c时,没有进入循环
while (p1<=p2)
{
*(p2 + strlen(str2)) = *p2;
//第一次进入循环时的解释//对p2 + strlen(str2)这个地址上的内容进行赋值,所以使用间接引用
//p2 + strlen(str2)的含义是\0所在的地址往后偏移str2个长度
//最终达到把\0移动到str2字符串数组长度之后的位置上,以便插入str2这个字符串
p2--;
}
while (*str2 != 0)
{
*p1 = *str2;
p1++;
str2++;
}//①的情况下:为什么c本来应该出现的位置不是空而是\0呢?
//主函数中定义char str[20] = "abcd";//不完全初始化,后面没有初始化的部分全部都是'\0'
}
字符串练习题2
//6.翻转字符串
//7.判断是否回文(回文指的是顺读和逆读都一样的字符串) “abcdcba”
void T6(char* str);
int T7(char* str);
int main()
{
char str[] = "123456";
T6(str);
printf("%s\n", str);
printf("%d\n", T7("123456"));
printf("%d\n", T7("abcdcba"));
return 0;
}
void T6(char* str)
{
char* begin = str;
char* end = str + strlen(str) - 1;
char c;
while (begin < end)
{
c = *begin;
*begin = *end;
*end = c;
begin++;
end--;
}
}
int T7(char* str)
{
char* begin = str;
char* end = str + strlen(str) - 1;
int Bool = 0;
while (begin < end)
{
if (*begin == *end)
{
begin++;
end--;
}
if (*begin != *end)
{
return Bool;
}
}
while (begin = end)
{
Bool++;
return Bool;
}
return Bool;
}
getchar()
int main()
{
printf("%c\n", getchar());
printf("%c\n", getchar());
printf("%c\n", getchar());
printf("%c\n", getchar());
printf("%c\n", getchar());
//输入字符后可以读取一位
//输入abc\0,实际上需要读取四位,最后的\0也会被获取,所以再输入ab时只能读取a
return 0;
}
要求:未知多少位的情况下,需要将所有内容回显出来
int main()
{
//while (getchar() != '\n')
//{
// printf("%c", getchar());
//}
//以12345\n为例,输出24且无法结束程序
//getchar() != '\n'中getchar得到135,printf("%c", getchar())中getchar()得到24\n
//以1234\0为例,输出24后可以结束程序
//getchar() != '\n'中getchar得到13\n,printf("%c", getchar())中getchar()得到24
//getchar()每次读取一个字符后无论是否输出都不会存放
char c;
//while (c = getchar() != '\n')
//!=的优先级比=高,因此先执行getchar() != '\n'返回真也就是1
//所以c(char型)存放的是1,会显示出方块
while ((c = getchar()) != '\n')
{
printf("%c", c);
}
return 0;
}
暂存用户输入的一段字符,以便所需时取用
char* GetString();
int main()
{
char* str = GetString();
printf("%s\n", str);
return 0;
}
char* GetString()
{
char c;
int size = 5;
char* str = (char*)malloc(size);
int count = 0;
char* newstr = NULL;
char* pMark = str;
//从输入缓冲区中取字符
while ((c = getchar()) != '\n')
{
//取下的字符放到字符数组里
*str = c;
//计数累计
count++;
str++;
//判断是否能放下
if (count + 1 == size)
{
//放不下
//变字符串
*str = '\0';
//size增大
size += 5;
//开辟一个新的空间
newstr = (char*)malloc(size);
//将老字符串拷贝到新字符数组中
strcpy_s(newstr, size, pMark);
//释放老字符串
free(pMark);
//找到新字符串结尾位置
str = newstr + count;
//标记指向字符串首地址
pMark = newstr;
}
}
//变字符串
*str = '\0';
return pMark;
}
比较两个字符串:strcmp
//返回值Int类型,参数char*
//返回值为0时,字符串1等于字符串2;为-1时,字符串1小于字符串2;为1时,字符串1大于字符串2
//按位比较而不是比较长度~
//strncmp 比较部分字符串(前几位)
int MYstrcmp2(char* str1, char* str2);
int MYstrcmp(char* str1,char* str2);
int main()
{
printf("%d\n", MYstrcmp("ac", "abc"));
printf("%d\n", MYstrcmp("ab", "abc"));
printf("%d\n", MYstrcmp("abc", "abc"));
printf("----------------------\n");
printf("%d\n", strcmp("ac", "abc"));//第二位上,c的ASCII码比b大,因此输出1
printf("%d\n", strcmp("ab", "abc"));
printf("%d\n", strcmp("abc", "abc"));
printf("----------------------\n");
printf("%d\n", MYstrcmp2("ac", "abc"));//第二位上,c的ASCII码比b大,因此输出1
printf("%d\n", MYstrcmp2("ab", "abc"));
printf("%d\n", MYstrcmp2("abc", "abc"));
printf("----------------------\n");
printf("%d\n", strncmp("ab", "abc", 2));
return 0;
}
//strcmp函数的仿写
int MYstrcmp(char* str1,char* str2)
{
while (*str1!='\0' && *str2!='\0')//只要有一个到'\0'就跳出循环
{
if (*str1<*str2)
{
return -1;
}
else if (*str2<*str1)
{
return 1;
}
else
{
str1++;
str2++;
}
}
if (*str1 < *str2)
{
return -1;
}
else if (*str2 < *str1)
{
return 1;
}
else
{
return 0;
}
}
int MYstrcmp2(char* str1, char* str2)
{
while (*str1!='\0'||*str2!='\0')//两个都到'\0'才跳出循环
{
if (*str1 < *str2)
{
return -1;
}
else if (*str2 < *str1)
{
return 1;
}
else
{
str1++;
str2++;
}
}
return 0;
}
/*思路:
定义一个char类型字符(传入)
用malloc函数在堆区开辟一个新的空间存字符串
定义一个char* 类型指针标记字符串首地址
定义一个char* 类型字符串为空
定义一个int类型变量计数
while循环,当传入字符c不等于‘\n’时
字符c的值传入malloc定义的字符串,
字符串地址后移
计数
当(统计次数 + 1)等于开辟空间大小时
给字符串赋‘\0’
增大空间
给新字符串开辟增大后的空间
调用strcpy函数将原有字符串(标记指针所指向)内容存到新的字符串中
释放原字符串的空间
标记指针指向新字符串的首地址
最后为字符串赋‘\0’
返回 标记指针首地址
*/