目录
前言
C语言对字符和字符串的使用极其频繁,C语言有字符类型但没有字符串类型,通常将字符串放在常量字符串和字符数组中,通常引用字符串函数来处理字符串的相关操作。
一、函数介绍
1.1 strlen
size_t strlen ( const char * str );
字符串长度函数,字符串以'\0'作为结束标志,strlen计算不包括‘\0’的字符串长度(或者说字符串中字符的个数),函数的返回值为无符号数。不能通过长度相减的正负来判断字符串的长短。
示例
#include <stdio.h>
#include <string.h>int main ()
{
char szInput[256];
printf ("请输入一个字符串: ");
gets (szInput);
printf ("字符串长度(单位为元素长度)为 %u。\n",(unsigned)strlen(szInput));
return 0;
}
输出
请输入一个字符串: just testing
字符串长度(单位为元素长度)为 12 。
1.2 strcpy
char* strcpy ( char * destination , const char * source);
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]="Sample string";
char str2[40];
char str3[40];
strcpy (str2,str1);
strcpy (str3,"copy successful");
printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
return 0;
}
输出:
str1: Sample string
str2: Sample string
str3: copy successful
1.3 strcat
char * strcat ( char * destination , const char * source );
示例
#include <stdio.h>
#include <string.h>
int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}
输出
these strings are concatenated.
1.4 strcmp
int strcmp ( const char * str1 , const char * str2 );
返回值 | 说明 |
<0 | 第一个不匹配的字符在 str1 中的值低于 str2 中的值 |
0 | 两个字符串的内容相等 |
>0 | 第一个不匹配的字符在 PTR1 中的值大于在 PTR2 中的值 |
#include <stdio.h>
#include <string.h>int main ()
{
char key[] = "apple";
char buffer[80];
do {
printf ("Guess my favorite fruit? \n");
scanf ("%79s",buffer);
} while (strcmp (key,buffer) != 0);
puts ("Correct answer!");
return 0;
}
Guess my favourite fruit?orange
Guess my favourite fruit?apple
Correct answer!
1.5 strncpy
char * strncpy ( char * destination , const char * source , size_t num );
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]= "To be or not to be";
char str2[40];
char str3[40];
strncpy ( str2, str1, sizeof(str2) );
strncpy ( str3, str2, 5 );
str3[5] = '\0';
puts (str1);
puts (str2);
puts (str3);
return 0;
}
To be or not to be
To be or not to be
To be
1.6 strncat
char * strncat ( char * destination , const char * source , size_t num );
从字符串追加字符函数,将原字符串的第一个数字字符追加到目标字符串,外加一个‘\0’。如果原字符串的长度小于 num,则只有复制‘\0’之前的内容。
示例
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[20];
char str2[20];
strcpy (str1,"To be ");
strcpy (str2,"or not to be");
strncat (str1, str2, 6);
puts (str1);
return 0;
}
输出
To be or not
1.7 strncmp
int strncmp ( const char * str1 , const char * str2 , size_t num );
返回值 | 说明 |
<0 | 第一个不匹配的字符在 str1 中的值低于 str2 中的值 |
0 | 两个字符串的内容相等 |
>0 | 第一个不匹配的字符在 str1 中的值大于在 str2 中的值 |
#include <stdio.h>#include <string.h>int main (){char str [][ 5 ] = { "R2D2" , "C3PO" , "R2A6" };int n ;puts ( "Looking for R2 astromech droids..." );for ( n = 0 ; n < 3 ; n ++ )if ( strncmp ( str [ n ], "R2xx" , 2 ) == 0 ){printf ( "found %s\n" , str [ n ]);}return 0 ;}
Looking for R2 astromech droids...
found R2D2
found R2A6
1.8 strstr
char * strstr ( const char * str1 , const char * str2 );
#include <stdio.h>#include <string.h>int main (){char str [] = "This is a simple string" ;char * pch ;pch = strstr ( str , "simple" );strncpy ( pch , "sample" , 6 );puts ( str );return 0 ;}
This is a sample string
1.9 strtok
char * strtok ( char * str , const char * sep );
- sep参数是个字符串,定义了用作分隔符的字符集合 。
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时 拷贝的内容并且可修改。)
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
#include <stdio.h>#include <string.h>int main (){char str [] = "- This, a sample string." ;char * pch ;printf ( "Splitting string \"%s\" into tokens:\n" , str );pch = strtok ( str , " ,.-" );while ( pch != NULL ){printf ( "%s\n" , pch );pch = strtok ( NULL , " ,.-" );}return 0 ;}
Splitting string "- This, a sample string." into tokens: This a sample string
1.10 strerror
char * strerror ( int errnum );
函数用来获取指向错误消息字符串的指针
示例
#include <stdio.h>#include <string.h>#include <errno.h> // 必须包含的头文件int main (){FILE * pFile;
pFile = fopen ("unexist.ent","r");
if ( pFile == NULL )printf ( "Error opening file unexist.ent: %s\n" , strerror ( errno ));//errno: Last error numberreturn 0 ;}
Error opening file unexist.ent: No such file or directory
1.11 memcpy
void * memcpy ( void * destination , const void * source , size_t num );
#include <stdio.h>#include <string.h>struct {char name [ 40 ];int age ;} person , person_copy ;int main (){char myname [] = "Pierre de Fermat" ;memcpy ( person . name , myname , strlen ( myname ) + 1 );person . age = 46 ;memcpy ( & person_copy , & person , sizeof ( person ) );printf ( "person_copy: %s, %d \n" , person_copy . name , person_copy . age );r eturn 0 ;}
person_copy: Pierre de Fermat, 46
1.12 memmove
void * memmove ( void * destination , const void * source , size_t num );
#include <stdio.h>#include <string.h>int main (){char str [] = "memmove can be very useful......" ;memmove ( str + 20 , str + 15 , 11 );puts ( str );return 0 ;}
memmove can be very very useful.
1.13 memcmp
int memcmp ( const void * ptr1 ,const void * ptr2 ,size_t num );
返回值 | 说明 |
< | 两个内存块中不匹配的第一个字节在 ptr1 中的值低于 ptr2 中的值(如果评估为无符号字符值) |
=0 | 两个内存块的内容相等 |
>0 | 两个内存块中不匹配的第一个字节在 ptr1 中的值大于在 ptr2 中的值(如果评估为无符号字符值) |
#include <stdio.h>#include <string.h>int main (){char buffer1 [] = "DWgaOtP12df0" ;char buffer2 [] = "DWGAOTP12DF0" ;int n ;n = memcmp ( buffer1 , buffer2 , sizeof ( buffer1 ) );if ( n > 0 ) printf ( "'%s' is greater than '%s'.\n" , buffer1 , buffer2 );else if ( n < 0 ) printf ( "'%s' is less than '%s'.\n" , buffer1 , buffer2 );else printf ( "'%s' is the same as '%s'.\n" , buffer1 , buffer2 );return 0 ;}
'DWgaOtP12df0' is greater than 'DWGAOTP12DF0'.
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "hello world!";
memset(str + 1, 'A', 4);
puts(str);
return 0;
}
hAAAA world!
二、库函数模拟实现
2.1 模拟实现strlen
int my_strlen ( const char * str ){int count = 0 ;while ( * str ){count ++ ;str ++ ;}return count ;}
int my_strlen ( char * s ){char * p = s ;while ( * p != ‘\0’ )p ++ ;return p - s ;}
2.2 模拟实现strcpy
char * my_strcpy ( char * dest , const char* src ){char * ret = dest ;assert ( dest != NULL );// 使用时包含头文件assert.h,用于中止程序执行(如果使用空指针作为属性进行调用)assert ( src != NULL );while (( * dest ++ = * src ++ )){;}return ret ;}
2.3 模拟实现strcat
char * my_strcat ( char * dest , const char* src ){char * ret = dest ;assert ( dest != NULL );assert ( src != NULL );while ( * dest ){dest ++ ;}while (( * dest ++ = * src ++ )){;}return ret ;}
2.4 模拟实现strstr
char * strstr ( const char * str1 , const char * str2 ){char * cp = ( char * ) str1 ;char * s1 , * s2 ;if ( !* str2 )return (( char * ) str1 );while ( * cp ){s1 = cp ;s2 = ( char * ) str2 ;while ( * s1 && * s2 && ! ( * s1 -* s2 ) )s1 ++ , s2 ++ ;if ( !* s2 )return ( cp );cp ++ ;}return ( NULL );
2.5 模拟实现strcmp
int my_strcmp ( const char * src , const char * dst ){int ret = 0 ;assert ( src != NULL );assert ( dest != NULL );while ( ! ( ret = * ( unsigned char * ) src - * ( unsigned char * ) dst ) && * dst )++ src , ++ dst ;if ( ret < 0 )ret = - 1 ;else if ( ret > 0 )ret = 1 ;return ( ret );}
2.6 模拟实现memcpy
void * memcpy ( void * dst , const void * src , size_t count ){void * ret = dst ;assert ( dst );assert ( src );/**从较低地址复制到较高地址*/while ( count -- ){* ( char * ) dst = * ( char * ) src ;dst = ( char * ) dst + 1 ;src = ( char * ) src + 1 ;}return ( ret );}
2.7 模拟实现memmove
void* my_memmove(void* dest,void* str, size_t num)
{
void* ret = dest;
assert(dest && str);
//从低地址复制到高地址(前—>后)
if (dest<str)
{
while (num--)
{//*dest、*str类型不确定(char*)强制转化为(最小的地址空间)
*(char*)dest = *(char*)str;
dest = (char*)dest+1;
str = (char*)str+1;
}
}
else//从高地址复制到低地址(后—>前)
{
while (num--)
{
*((char*)dest + num) = *((char*)str + num);
}
}
return ret;
}