C语言字符串操作函数
1.strlen
strlen用于求一个C风格字符串的长度,函数原型为
#include size_t strlen(const char *s);
返回值为字符串的长度,当遇到‘\0‘时,认为字符串结束,‘\0‘不算入长度中。
#include #include
int main(void)
{char *str = "hello,world";int count =strlen(str);
printf("%d\n",count);return 0;
}
结果测试:11
测试结果符合预期,下面一三种方式实现自己的strlen函数。
size_t my_strlen1(const char *str)
{int count=0;
assert(str);//while(str[count++]);//return count-1;
while(*str++)
count++;returncount;
}
size_t my_strlen2(const char *str)
{
assert(str);if(*str == ‘\0‘) return 0;else return my_strlen2(++str)+1;
}
size_t my_strlen3(const char *str)
{char *headstr =str;
assert(str);while(*++str);return str -headstr;
}
第一种使用一次遍历字符串,当字符不为‘\0‘时,count++;
第二种使用递归
第三种使用指针的剪发,用指向最后一个字符的指针减去指向首字符的指针。
2.strnlen
strnlen的原型为
#include size_t strnlen(const char *s, size_t maxlen);
strnlen的功能相当于一个计数器,函数从s的开头往下数,直到遇见‘\0‘或者计数器达到maxlne的值时,停止计数。
其用途主要在于网络图形中,字节流一般是没有‘\0‘的,所以,使用strlen一般会有问题,所有引入strnlen.
3.strcpy
strcpy的原型为
#include
char *strcpy(char *dest, const char *src);
strcpy的作用是将src开始的字符串(包括‘\0‘)复制到以dest为起始点的地址空间,返回值为指向dest的指针。
#include #include
intmain()
{char dest[100];char *src = "hello,world";
strcpy(dest,src);
printf("%s\n",dest);return 0;
}
测试结果:hello,world
符合预期
实现自己的strcpy
#include #include
char *my_strcpy(char *dest,const char *src)
{
assert(dest);
assert(src);while (*dest++ = *src++);returndest;
}
4.strncpy
strncpy的原型是
#include
char *strncpy(char *dest, const char *src, size_t n);
该函数同样字符串拷贝函数,与strcpy不同的是,多了一个参数n。函数的作用是将src所指向的字符串中前n个字符复制到dest中。
5.strcmp
#include
int strcmp(const char *s1, const char *s2);
strcmp用来比较字符串s1和s2的大小,比较方式为字典式比较,比较标准为字符的ASCII值,比如"erfas"和"eradfasa";
逐个比较前两个字符相等,第三个字符‘f’大于‘a‘,所以第一个字符串大。
当s1 大于 s2时,返回正数;
当s1 等于 s2时,返回0;
当s1 小于 s2时,返回负数;
#include #include
intmain()
{char *s1 = "hello wolrd";char *s2 = "change world";int count =strcmp(s1,s2);
printf("%d\n",count);return 0;
}
这段代码在vs2010下结果为1,在gcc下测试结果为5
C语言标准只规定当s1 大于 s2时,返回值为正数,vs一律返回1,而gcc返回ASCII值的差,所以为了程序的
可移植性,不要写出
strcmp(s1,s2) == 1
这样的代码,建议这样写
strcmp(s1,s2) > 0
下面我们尝试实现自己的strcmp
#include #include
int my_strcmp(const char *s1,const char *s2)
{
assert(s1);
assert(s2);while((*s1) == (*s2))
{if((*s1) == ‘\0‘)return 0;
s1++;
s2++;
}if((*s1) - (*s2) > 0) return 1;else return -1;
}
6.strncmp
strncmp的原型为
#include
int strncmp(const char *s1, const char *s2, size_t n);
该函数基本与strcmp差不多,但是只比较两个字符串的前n个字符。
7.strstr
strstr的原型为
#include
char *strstr(const char *haystack, const char *needle);
判断needle是否是haystack的子串,如果是,返回needle在haystack中首次出现的地址,否则,返回NULL
#include #include
intmain()
{char *s1 = "hello,world";char *s2 = "llo,w";char *s3 =strstr(s1,s2);
printf("%s\n",s3);return 0;
}
测试结果为:
llo,world
结果符合预期
8.memset
memset的原型为
#include
void *memset(void *s, int c, size_t n);
memset的作用是将s所指向的内存中的前n个字节全部置为字符c的ASCII值。
#include #include
intmain()
{char s[100];
memset((char *)s,‘c‘,10);
s[10] = ‘\0‘;
printf("%s\n",s);return 0;
}
测试结果:cccccccccc
9.memcpy
memcpy
#include
void *memcpy(void *dest, const void *src, size_t n);
将src的数据复制n个到dest
#include #include
intmain()
{char src[100] = "hello,world";char dest[100];
memcpy(dest,src,11);
printf("%s\n",dest);return 0;
}
测试结果:hello,world
符合预期
memcpy不考虑内存重叠
10.memmove
memmove的原型为
#include
void *memmove(void *dest, const void *src, size_t n);
memmove与memcpy相似,但可以处理内存重叠的问题。