定义
字符串就是一串零个或多个字符,并且以一个位模式为全0的NULL字节结尾。因 此,字符串所包含的字符内部不能出现NULL字节。字符串是一种重要的数据类型,但是c语言并没有显示的字符串数据类型,这是因为字符串以字符串常量的形式出现或存储于字符数组中。
字符串长度函数strlen( const char *str)
size_t my_strlen(const char *str)
{
int count = 0;
assert(str);
while (*(str++) != '\0')
{
count++;
}
return count;
}
int main()
{
char *s = "hello";
printf("%s has %d chars",s,my_strlen(s));
getchar();
return 0;
}
注意:strlen()函数的返回值为size_t, 实际上是unsigned int 。永远为大于0的值。有时候需要强制类型转换。
不受限制的字符串函数
1.复制字符串函数strcpy(char *dst ,char const*src)
功能:将参数src字符串复制到dst参数。以字符NULL结尾。
char * my_strcpy(char*dst, char*src)
{
assert(dst);
assert(src);
while (*(dst++) = *(src++))
{
;
}
return dst;
}
int main()
{
char arr[100] = {0};
my_strcpy(arr,"The road is tortuous" );
printf("%s\n",arr);
return 0;
}
注意:
<1>.必须保证目标字符数组的空间足够容纳需要复制的字符串。
<2>.源空间必须以’\0’结束,否则程序发生崩溃。
<3>.将char*作为函数返回值是为了更好的实现链式访问。
2.连接字符串函数strcat(char *dst,char const *src)
功能:将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。
char * my_strcat(char *dst, const char *src)
{
char *start = dst;
int len_dst = strlen(dst);
dst += len_dst;
while (*dst++ = *src++)
{
;
}
return start;
}
int main()
{
char str1[10] = "hello ";
char *str2 = "world!";
printf("%s\n", my_strcat(str1, str2));
return 0;
}
注意:必须保证目标字符数组的剩余空间足够保存整个的源字符串,不能出现重叠。
3.字符串比较函数strcmp(char const *s1,char const *s2)
功能:比较两个字符串s1,s2的大小,如果s1<s2,函数返回一个小于零的值;s1>s2,函数返回一个大于零的值;s1=s2,则返回零值。
int my_strcmp(char* s1, char* s2)
{
assert(s1);
assert(s2);
while (*s1 == *s2)
{
if (*s1 == '\0')
return 0;
}
return *s1 - *s2;
}
int main()
{
char *s1 = "abcde";
char *s2 = "sbduiwqdnd";
printf("%d\n",my_strcmp(s1,s2));
return 0;
}
注意:
<1>.c标准没有规定用于提示不相等的具体值,只规定大于零的值,小于零的值,等于零的值。
<2>.必须以一个NULL字节结尾,如果没有,那比较结果将毫无意义。
长度受限的字符串函数
1.strncpy( const *dst ,char const *src ,size_t len)
和strcpy()函数一样,把源字符串的字符复制到目标数组。它是向dst写入len个字符。如果strlen(src)的值小于len,dst数组就用额外的NULL字节填充到len长度。大于就正常复制到dst中。它的结果将不会以NULL字节结尾。
char* my_strncpy(char *dst, const char *src, int len)
{
char *copy = dst;
assert(src && dst);
while (len&& (*dst++ = *src++))
{
len--;
}
if (len> 0)
{
while (--len)
{
*dst++ = '\0';
}
}
return copy;
}
int main()
{
char string[100] = { 0 };
int len = strlen("hahh");
printf("%s\n", my_strncpy(string, "hahh", len));
return 0;
}
2.strncat( const *dst ,char const *src ,size_t len)
strncat()是从src中最多复制len个字符到目标数组的后面。但是,它总是在结果字符串后面添加一个NULL字节。不考虑目标参数除去原先存在的字符串之后留下的空间是否足够。
char* my_strncat(char *dst, const char *src, int len)
{
char *cat = dst;
assert(src && dst);
while (*dst != '\0')
{
*dst++;
}
while (len&& *src)
{
*dst++ = *src++;
len--;
}
*dst = '\0';
return cat;
}
int main()
{
char str1[10] = "hello ";
char *str2 = "world!";
printf("%s\n", my_strncat(str1, str2,3));
return 0;
}
3.strncmp( char const *s1 ,char const *s2 ,size_t len)
它最多比较len个字节,如果在第len个字符之前存在不相等字符,停止比较;返回结果。否则返回零。
int my_strcnmp(char* s1, char* s2,size_t len)
{
assert(s1 && s2);
if (!len)
return 0;
while (--len&& *s1 && *s1 == *s2)
{
s1++;
s2++;
}
return *s1 - *s2;
}
int main()
{
char *s1 = "abcde";
char *s2 = "abcdef";
printf("%d\n",my_strcnmp(s1,s2,5));
return 0;
}
字符串查找函数
1.查找一个字符
char *strchr(char const *str ,int ch) ;
char *strrchr(char const *str ,int ch);
它们的第二个参数是一个整形值,在str中查找ch第一次出现的位置,找到后返回一个指向该位置的指针。否则返回NULL指针.
2.查找任何几个字符
char *strpbrk(char const*str,char const *group);
返回一个指向str中第一个匹配group中任何一个字符的字符位置,没找到,返回NULL指针
3.查找一个子串
char *strstr(char const *s1,char const *s2);
在s1中查找s2第一次出现的起始位置,并返回一个指向该位置的指针。如果s2没有完整出现在s1的任何地方,函数将返回一个NULL指针。s2若是一个空字符串,则函数返回s1。
4.查找标记
char *strtok(char *str,char const *sep);
功能:分解字符串为一组标记串。str为要分解的字符串,sep为分隔符字符串集合。
int main()
{
char buf[] = "hello@boys@this@is@apple";
char*temp = strtok(buf, "@");
while (temp)
{
printf("%s ", temp);
temp = strtok(NULL, "@");
}
return 0;
}