目录
一、字符串的概念
我们可以把字符串储存在char类型的数组中,如果char类型的数组末尾包含一个表示字符串末尾的空字符\0,则该数组中的内容就构成了一个字符串
因为字符串需要用\0结尾,所以在定义字符串的时候,字符数组的长度要预留多一个字节用来存放\0,\0就是数字0
例如
char name[21]; // 定义一个最多存放20个英文字符或十个中文的字符串
- 字符串也可以存放中文和全角的标点符号,一个中文字符占两个字节(GBK编码)。char strname[21]用于存放中文的时候,最多只能存10个汉字。
- 字符串采用双引号包含起来,如:”hello,world”、”你好C语言”
二、占用内存的情况
一个字符占用一字节的内存,字符串定义时数组的大小就是字符串占用内存的大小
char str[21]; // 占用21字节的内存
char str[1024]; // 占用1024字节的内存
三、字符串的初始化
char name[21];
memset(name,0,sizeof(name));//采用memset函数初始化字符串
四、字符串与指针
数组名是数组元素的首地址,字符串是字符数组,所以在获取字符串的地址的时候,不需要用&取地址
char name[21];
memset(name,0,sizeof(name));
strcpy(name,"hello,xiaoqiu");//把hello,xiaoqiu赋值给name
printf("%s\n",name);
五、字符串的结尾标志
- 字符串的结尾标志是0,如果没有结尾标志,后面的内容将被丢弃
- 结尾标志后面的内容如何处理
#include <stdio.h>
#include <string.h>
int main()
{
char name[21];
memset(name,0,sizeof(name));
strcpy(name,"hello,xiaoqiu");//把hello,xiaoqiu赋值给name
name[5]=0;//强制把第6个元素赋值为0
printf("%s\n",name);
return 0;
}
运行效果
以上代码输出的结果是 hello ,但是,在内存中的值仍是hello0xiaoqiu,后面的 xiaoqiu 成了内存中的垃圾值
不要让字符串的内存中有垃圾值,容易产生意外的后果。这就是字符串的初始化不建议采用把第一个元素的值置为0的原因(name[0]=0)
六、字符串常用的库函数
1、获取字符串的长度(strlen)
size_t strlen( const char* str);
- 功能:计算字符串的有效长度,不包含 \0
- 返回值:返回字符串的字符数
- strlen 函数计算的是字符串的实际长度,遇到第一个\0结束
- 函数返回值一定是size_t,是无符号的整数,即typedef unsigned int size_t
- 如果您只定义字符串没有初始化,求它的长度是没意义的,它会从首地址一直找下去,遇到0停止
- 很多人对 sizeof 和 strlen 有点分不清楚 。sizeof 返回的是变量所占的内存数,不是实际内容的长度
举个例子
#include <stdio.h>
#include <string.h>
int main()
{
char name[21];
memset(name,0,sizeof(0));
strcpy(name,"xiaoqiu");
printf("strlen=%d\n",strlen(name)); // 7
printf("sizeof=%d\n",sizeof(name)); // 21 sizeof 返回的是变量所占的内存数
return 0;
}
运行效果
自己实现一个 strlen 函数
#include <stdio.h>
#include <string.h>
int mystrlen(const char* str)
{
int i = 0;
while( str[i]!='\0' ) {
i++;
}
return i;
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,"xiaoqiu");
char name2[21];
memset(name2,0,sizeof(0));
strcpy(name2,"baidu");
printf("mystrlen=%d\n",mystrlen(name1)); // 7
printf("mystrlen=%d\n",mystrlen(name2)); // 5
return 0;
}
运行效果
2、字符串复制或赋值(strcpy)
char *strcpy(char* dest, const char* src);
- 功 能: 将参数src字符串拷贝至参数dest所指的地址
- 返回值: 返回参数dest的字符串起始地址
- 复制完字符串后,在dest后追加0
- 如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误情况
自己实现一个 strcpy 函数
#include <stdio.h>
#include <string.h>
char *mystrcpy(char* dest,const char* src)
{
size_t i = 0;
while (src[i] != '\0') {
dest[i] = src[i];
i++;
}
dest[i]='\0';
return dest;
}
int main()
{
char name[21];
memset(name,0,sizeof(0));
mystrcpy(name,"xiaoqiu");
printf("strlen=%d\n",strlen(name)); // 7
printf("sizeof=%d\n",sizeof(name)); // 21
return 0;
}
运行效果
3、字符串复制或赋值(strncpy)
char * strncpy(char* dest,const char* src, const size_t n);
- 功能:把src前n字符的内容复制到dest中
- 返回值:dest字符串起始地址
- 如果src字符串长度小于n,则拷贝完字符串后,在dest后追加0,直到n个
- 如果src的长度大于等于n,就截取src的前n个字符,不会在dest后追加0
- dest必须有足够的空间放置n个字符,否则可能会造成缓冲溢出的错误情况
自己实现一个 strncpy 函数
#include <stdio.h>
#include <string.h>
char *mystrncpy(char* dest,const char* src,const size_t n)
{
int len = (strlen(src)>n)?n:strlen(src);
size_t i = 0;
for (i=0;i<len;i++) {
dest[i] = src[i];
}
dest[i]='\0';
return dest;
}
int main()
{
char name[21];
memset(name,0,sizeof(0));
mystrncpy(name,"xiaoqiu",4);
printf("strlen=%d\n",strlen(name)); // 4
printf("sizeof=%d\n",sizeof(name)); // 21
return 0;
}
运行效果
4、字符串拼接(strcat)
char *strcat(char* dest,const char* src);
- 功能:将src字符串拼接到dest所指的字符串尾部
- 返回值:返回dest字符串起始地址
- dest最后原有的结尾字符0会被覆盖掉,并在连接后的字符串的尾部再增加一个0
- dest要有足够的空间来容纳要拼接的字符串,否则可能会造成缓冲溢出的错误情况
自己实现一个 strncpy 函数
#include <stdio.h>
#include <string.h>
char *mystrcat(char* dest,const char* src)
{
int destlen = strlen(dest);
int i = 0;
for (i=0;i<strlen(src);i++) {
dest[destlen+i]=src[i];
}
dest[destlen+i]='\0';
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,"xiaoqiu");
char name2[21];
memset(name2,0,sizeof(0));
strcpy(name2,"hello");
mystrcat(name2,name1);
printf("%s\n",name2);
return 0;
}
运行效果
5、字符串拼接(strncat)
char *strncat (char* dest,const char* src, const size_t n);
- 功能:将src字符串的前n个字符拼接到dest所指的字符串尾部
- 返回值:返回dest字符串的起始地址
- 如果n大于等于字符串src的长度,那么将src全部追加到dest的尾部,如果n小于字符串src的长度,只追加src的前n个字符
- strncat会将dest字符串最后的0覆盖掉,字符追加完成后,再追加0
- dest要有足够的空间来容纳要拼接的字符串,否则可能会造成缓冲溢出的错误情况
自己实现一个 strncat 函数
#include <stdio.h>
#include <string.h>
char *mystrncat(char* dest,const char* src,size_t n)
{
/* 方法一
int len = strlen(src);
if (len > n) len = n;
else if (len < n) len = strlen(src);
*/
// 方法二
int len = (strlen(src)>n)?n:strlen(src);
int destlen = strlen(dest);
int i = 0;
for (i=0;i<len;i++) {
dest[destlen+i]=src[i];
}
dest[destlen+i]='\0';
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,"xiaoqiu");
char name2[21];
memset(name2,0,sizeof(0));
strcpy(name2,"hello");
mystrncat(name2,name1,4);
printf("%s\n",name2);
return 0;
}
运行效果
6、字符串比较(strcmp、strncmp)
int strcmp(const char *str1, const char *str2 );
功能:比较str1和str2的大小
返回值:相等返回0,str1大于str2返回1,str1小于str2返回-1
自己实现一个strcmp 函数
#include <stdio.h>
#include <string.h>
int mystrcmp(const char *str1,const char *str2)
{
int i = 0;
int len = 0;// str1 和 str2 较短的字符串长度
if ( strlen(str1) > strlen(str2) ) len = strlen(str2);
else len = strlen(str1);
for (i = 0;i < len;i++) {
if (str1[i]==str2[i]) continue;
else break;
}
// 两个字符串相等
if ( (i==len) && (strlen(str1)==strlen(str2)) ) return 0;
// 两个字符串不相等
else if (str1[i]>str2[i]) return 1;
else return -1;
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,",xiaoqiu");
char name2[21];
memset(name2,0,sizeof(0));
strcpy(name2,"hello");
printf("%d\n",mystrcmp(name1,name2));
return 0;
}
运行效果
int strncmp(const char *str1,const char *str2 ,const size_t n);
功能:比较str1和str2前n个字符的大小
返回值:相等返回0,str1大于str2返回1,str1小于str2返回-1
两个字符串比较的方法是比较字符的ASCII码的大小,从两个字符串的第一个字符开始,如果分不出大小,就比较第二个字符,如果全部的字符都分不出大小,就返回0,表示两个字符串相等
自己实现一个strncmp函数
#include <stdio.h>
#include <string.h>
int mystrcmp(const char *str1,const char *str2,size_t n)
{
int i = 0;
for (i = 0;i < n;i++) {
if (str1[i]==str2[i]) continue;
else break;
}
if (i==n) return 0;
else if (str1[i]>str2[i]) return 1;
else return -1;
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,",xiaoqiu");
char name2[21];
memset(name2,0,sizeof(0));
strcpy(name2,"hello");
printf("%d\n",mystrcmp(name1,name2,4));
return 0;
}
运行效果
7、字符查找(strchr、strrchr)
char *strchr(const char *s,const int c);
返回一个指向在字符串s中第一个出现c的位置,如果找不到,返回0
自己实现一个strchr函数
#include <stdio.h>
#include <string.h>
char *mystrchr(const char *s,const int c)
{
int i = 0;
int len = strlen(s);
for (i = 0;i<len;i++) {
if (s[i]==c)
return (char *)s+i;
}
return 0;
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,",xiaoqiu");
printf("%s\n",mystrchr(name1,'q'));
return 0;
}
运行效果
char *strrchr(const char *s,const int c);
返回一个指向在字符串s中最后一个出现c的位置,如果找不到,返回0
自己实现一个strrchr函数
#include <stdio.h>
#include <string.h>
char *mystrrchr(const char *s,const int c)
{
int i = 0;
for (i = strlen(s)-1;i>=0;i--) {
if (s[i]==c)
return (char *)s+i;
}
return 0;
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,",qqqxiaoqiu");
printf("%s\n",mystrrchr(name1,'q'));
return 0;
}
运行效果
8、字符串查找(strstr)
char *strstr(const char* str,const char* substr);
- 功能:检索子串在字符串中首次出现的位置
- 返回值:返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回0
自己实现一个 strstr 函数
#include <stdio.h>
#include <string.h>
char *mystrstr(const char* str,const char* substr)
{
char* pos = (char *)str;//要被检索的 C 字符串
char* pos1 = NULL;
while (1) {
if (pos[0]==0) break; // 如果要被检索的 C 字符串已经结束 break
pos1 = strchr(pos,substr[0]); // 在pos中查找子字符串的首字符。
if (pos == 0) return 0; // 如果没有找到,直接返回0
if ( strncmp(pos1,substr,strlen(substr)) ==0 ) return pos1;// 如果找到了,返回找到的地址。
pos++;// 待搜索的位置后移一个字节。
}
}
int main()
{
char name1[21];
memset(name1,0,sizeof(0));
strcpy(name1,",qqqxiaoqiu");
printf("%s\n",mystrstr(name1,"xiao"));
return 0;
}
运行效果
版权声明:本文为博主作者:易点点心动原创文章,版权归属原作者,如果侵权,请联系我们删除!
原文链接:https://blog.csdn.net/XiaoQiu__/article/details/126732659