一、字符串的定义及基本使用
1、什么是字符串?
被双引号引用的字符集合!例如:"hello"、"world",或者是以'\0'结尾的字符数组
例如:
char a[] = {'a','b','\0'}
注意:"hello" 中其实在末尾也'\0'只是我们看得到,也就是说字符串一定是以'\0'结尾的
//验证"hello"中有字符'\0'
#include <stdio.h>
int main()
{
char *p;
p = "hello";
printf("%d\n",*(p+5));
return 0;
}
输出结果为0则说明结尾是'0'
2、字符串和字符数组的联系及区别
可以把字符串当作字符数组一样处理,字符数组不一定可以当作字符串处理,因为字符数组中不一定有'0'。
char ch[] = {'a','b','\0','c','d'};
这种情况我们可以把数组ch当成字符串“ab”
在实际工作过程中我们经常会有如下需求,我们需要用一个字符数组用保存多个字符,并且 需要将这多个字符当成字符串 ,但是我们在定义字符数组的时候只知道需要保存的字符的最大 的数目(假设是30),实际存储的时候存储的字符可能会小于30。
char name[ 30 ] ;memset(name, 0, sizeof(name));注意:在定义字符数组长度的时候通常要比实际要存储的字节数的数目+1(因为最后需要留一 个字节存 ’ \0 ’ )
3、字符串的操作
#include <stdio.h>
int main()
{
//字符串的操作
char *str;
char a[] = {"hello"};
//可以通过指针str来操作ch
str = ch;
//方法1:
str[1] = 'a'; //当一个指针指向了一个数组以后,我们就可以通过指针使用下标法直接访问数组中的元素
//方法2:
*(str+1) = 'a';
//也可以将字符串变量赋值给一个指针变量
char *p = "hello";
return 0;
}
注意:p是一个指针变量,应该保存的是一个地址,因此 char *p = "hello"; 并不是将字符串"hello"赋值给 指针变量p,而是将存储字符串 "hello"的内存空间的首地址赋值给p。
4、将字符数组中的每个元素赋值为'\0'
我们将要用到函数memset()
#include <stdio.h>
void *memset(void *s,int c,size_t n);
#include <stdio.h>
#include <string.h>
int main()
{
char a[10];
memset(ch,0,sizeof(a)); //memset(ch,0,sizeof(a));
return 0;
}
二、常见的字符串处理函数
1、atoi函数
#include <stdlib.h>int atoi(const char *nptr);
功能:将字符串转换成int类型的整数,返回转换后的整数值
//编写代码实现atoi函数
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p = "1234";
int a = atoi(p);
printf("%d\n",a);
return 0;
}
2、atof函数
#include <stdlib.h>double atof(const char *nptr)
功能:将字符串转换成double类型的浮点数,返回转换后的浮点数
//将char类型转换为double类型的浮点数,并返回转换后的浮点数
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p = "123.456";
double a = atof(p);
printf("%f\n",a);
return 0;
}
3、strlen函数
#include <string.h>size_t strlen(const char *s);
功能:计算字符串的长度
//计算字符串的长度
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "hello";
char arr[] = ['A','B','\0','D'];
printf("%d %d\n",strlen(ch),strlen(arr));
return 0;
}
练习:编程实现strlen函数
#include <stdio.h>
int my_strlen(char ch[]) //int my_strlen(char *ch)
{
int cnt = 0;
int i = 0;
while(ch[i] != '\0')
{
cnt++;
i++;
}
return cnt;
}
4、strcpy函数
#include <string.h>char *strcpy(char *dest, const char *src);功能:把src所指向的字符串复制到dest所指向的空间中,'\0'也会拷贝过去参数:dest:目的字符串首地址src:源字符首地址返回值:成功:返回dest字符串的首地址失败:NULL
//示例代码
#include <stdio.h>
#include <string.h>
int main()
{
char *src = "hello";
chr ds[10] = {0};
strcpy(src,dst);
printf("dst:%s\n",dst);
return 0;
}
注意:dst的空间一定要大于从src中需要拷贝的内容所占用的空间,至少大1个字节(因为要给'\0'预留空间)
#include <stdio.h>
#include <string.h>
int main()
{
char a[4];
char b[4];
strcpy(b,"hello");
printf("b:%s\n",b);
printf("a:%s\n",a);
return 0;
}
5、strncpy函数
#include <string.h>char *strncpy(char *dest, const char *src, size_t n);功能:把src指向字符串的前n个字符复制到dest所指向的空间中,是否拷贝结束符看指定的长 度是否包含'\0'。参数:dest:目的字符串首地址src:源字符首地址n:指定需要拷贝字符串个数返回值:成功:返回dest字符串的首地址失败:NULL
注意:
(1)strcpy最多拷贝n个字节,如果前n个字节中没有'\0',最终也不会拷贝'\0'
(2)如果src的长度小于n,则会写入一些'\0'以保障总共写入n个bytes,strncpy在拷贝的时候如果前面的n个字节中已经有'\0'了,那么只拷贝到'\0',但是依然会往dest中继续写入'\0'以保障总共写入 了n个bytes。
//strncpy的实现
#include <stdio.h>
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n)
{
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
{
dest[i] = src[i];
}
for ( ; i < n; i++)
{
dest[i] = '\0';
}
return dest;
}
6、strcpy和strncpy的区别
如果你能够100%肯定dest的空间比src的空间大,可以使用strcpy在实际工作中为了避免溢出情况的产生我们尽量多使用strncpy问题又来了!如果使用strncpy的时候n比dest所指向的内存空间的大小要大那不是还是会产生 溢出吗?那么如何去规避这种溢出情况的产生呢?方法:先判断dest的长度len和n的大小,如果len>=n,则拷贝n个元素,如果len<n,则拷贝len个元素!
7、strcat函数
#include <string.h>char *strcat(char *dest, const char *src);功能:将src字符串连接到dest的尾部,‘\0’也会追加过去参数:dest:目的字符串首地址src:源字符首地址返回值:成功:返回dest字符串的首地址失败:NULL
//示例代码
#include <stdio.h>
#include <string.h>
int main()
{
char ch[20]; //char *ch;
memset(ch,0,sizeof(ch)); //ch = (char*)malloc(20);
strcpy(ch,"hello");
strcat(ch,"world");
printf("%s\n",ch);
return 0;
}
注意:ch的空间需要足够大
8、strncat函数
#include <string.h> char *strcat(char *dest, const char *src);功能:将src字符串连接到dest的尾部,‘\0’也会追加过去参数:dest:目的字符串首地址src:源字符首地址返回值:成功:返回dest字符串的首地址失败:NULL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *p;
p = (char *)malloc(20);
strcpy(p, "hello");
strncat(p, "world", 3);
printf("%s\n", p);
memset(p, 0, 20); //这是什么意思呢?
strcpy(p, "hello");
strncat(p, "world", 7);
printf("%s\n", p);
return 0;
}
9、strcmp函数
#include <string.h>int strcmp(const char *s1, const char *s2);功能:比较 s1 和 s2 的大小,比较的是字符ASCII码大小。参数:s1:字符串1首地址s2:字符串2首地址返回值:相等:0大于:>0 在不同操作系统strcmp结果会不同 返回ASCII差值小于:<0
原理:strcmp的执行的逻辑:将s1和s2中对应位置的字符一一比较,直到两个字符串全部遍历完成(如果还没有发现有不同的字符则说明两者相等),或者有两个字符不相等,则比较结束。如果s1中的字符的ASCII码比s2中的大则返回1,否则返回-1注意:有的编译器两个字符串不同的时不是返回1或者-1, 而是返回两个字符串中第一个不相 等的两个字符的ASCII码的差
#include <stdio.h>
int main()
{
printf("%d\n", strcmp("hello", "hello")); //结果为0
printf("%d\n", strcmp("hello", "heLlo")); //结果为1
printf("%d\n", strcmp("Hello", "heLlo")); //结果为-1
return 0;
}
10、strncmp函数
#include <string.h>int strncmp(const char *s1, const char *s2, size_t n);功能:比较 s1 和 s2 前n个字符的大小,比较的是字符ASCII码大小。参数:s1:字符串1首地址s2:字符串2首地址n:指定比较字符串的数量返回值:相等:0大于: > 0小于: < 0
/*在键盘上输入一串字符串
判断这个字符串和在程序中所设定的字符串是否相等
(最多比较6个字符)(不区分大小写)*/
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[10];
char key[] = "123456";
memset(ch1, 0, sizeof(ch1));
printf("请输入验证码:%s\n", key);
scanf("%s", ch1);
printf("%s\n", ch1);
return 0;
}
//在键盘上输入一串字符串,将其中的非字母和非数字的字符删除!
#include <stdio.h>
#include <string.h>
int main()
{
char ch1[10];
memset(ch1, 0, sizeof(ch1));
printf("请在键盘上输入一串字符(长度小于10)\n");
scanf("%s", ch1);
printf("%s\n", ch1);
return 0;
}
11、strstr函数
#include <string.h>char *strstr(const char *haystack, const char *needle);功能:在字符串haystack中查找字符串needle出现的位置参数:haystack:源字符串首地址needle:匹配字符串首地址返回值:成功:返回第一次出现的needle地址失败:NULL
我们经常使用strstr来判断某个字符串是否时另外一个字符串的字串!
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "ddddabcd123abcd333abcd";
char *p = strstr(src, "abcd");
printf("p = %s\n", p);
return 0;
}
12、strtok函数
#include <string.h>char *strtok(char *str, const char *delim);功能:来将字符串分割成一个个片段。当strtok()在参数s的字符串中发现参数delim中包含的分 割字符时, 则会将该字符改为\0 字符,当连续出现多个时只替换第一个为\0。参数:str:指向欲分割的字符串delim:为分割字符串中包含的所有字符返回值:成功:分割后字符串首地址失败:NULL
注意:
(1)在第一次调用时:strtok()必需给予参数s字符串
#include <stdio.h>
#include <string.h>
int main()
{
char a[100] = "abc-efg-hijk-lmn";
char *s = strtok(a, "-");//将"-"分割的子串取出
while (s != NULL) {
printf("%s\n", s);
s = strtok(NULL, "-");
}
return 0;
}