字符串函数探幽

字符串函数位于头文件 string.h 中,该文件包含字符串常用函数:strlen()、strcat()、strcmp()、strncmp()、strcpy()、strncpy()和sprintf()函数。

1、strlen()函数

1、用于得到字符串的长度。
函数原型 size_t __cdecl strlen(const char *_Str);,函数接收一个字符串的首地址。
2、strlen()函数遇到'\0’字符结束,即计算‘\0’之前的字符个数。

#include<stdio.h>
#include<string.h>
int main(){
	char string[]="Hello World!";
	printf("字符串长度:%d",strlen(string));	//输出12
	*(string+6) = '\0';
	printf("\n中间添加空字符:%d",strlen(string));	//输出6
	return 0;
} 

在这里插入图片描述

2、strcat()、strncat()函数

1、strcat()(代表 string concatenation)函数接收两个字符串参数。它将第二个字符串的一份拷贝添加到第一个字符串的结尾,从而使第一个字符串橙味一个新的组合字符串,第二个字符串并没有改变。这个函数返回它的第一个参数的值。

函数原型 char * __cdecl strcat(char * __restrict__ _Dest,const char * __restrict__ _Source);,函数接收两个参数,分别是目标字符串的首地址和原字符串的首地址,其中原字符串首地址应以const类型传入。

2、strcat()函数并不检查第一个数组是否能够容纳第二个字符串。如果没有为第一个数组分配足够大的空间,多出来的字符溢出到相邻存储单元时就会出现问题。

3、strncat()函数需要另一个参数来指明最多允许添加的字符的数目。
函数原型 char *__cdecl strncat(char * __restrict__ _Dest,const char * __restrict__ _Source,size_t _Count) __MINGW_ATTRIB_DEPRECATED_SEC_WARN;,函数接收三个参数,前两个参数和strcat()函数的参数相同,第三个参数指定最多允许添加的字符的数目_Count

4、函数在添加到_Count数目字符或遇到空字符停止,由二者中先符合的那一个来终止添加过程。_Dest数组应该足够大,以存放原始字符串,添加的最多_Count个字符和结束的空字符。

#include<stdio.h>
#include<string.h>
int main(){
	const char * const string="Hello World!";
	char dest1[100]="I'm Duary, ";
	char dest2[100]="I'm Duary, ";
	strcat(dest1,string);
	strncat(dest2,string,7);
	puts("dest1:");
	puts(dest1);	//输出dest1 
	puts("\ndest2:");
	puts(dest2);	//输出dest2 
	return 0;
} 

在这里插入图片描述

3、strcmp()、strncmp()函数

1、strcmp()函数进行字符串内容比较,可以用来不叫存放在不同大小数组里的字符串。
函数原型 int __cdecl strcmp(const char *_Str1,const char *_Str2);

2、strcmp()的返回值。
ANSI标准规定,①如果第一个字符串在字母表中的顺序先于第二个字符串,strcmp()返回一个赋值;
②如果两个字符串相同,它返回0;
③如果第一个字符串在字母表中的顺序落后于第二个字符串,它返回一个正数。
一般来说,strcmp()函数一直往后查找,直到找到第一对不一致的字符,然后它就返回相应的值。

3、实际上,strcmp()是按机器编码顺序进行比较的。这意味着字符的比较是根据它们的数字表示法,一般是 ASCII 值。

4、strncmp()函数比较字符串时,可以比较到字符串不同处,也可以比较完全由第三个参数指定的字符数。
函数原型

#include<stdio.h>
#include<string.h>
int main(){
	const char * const string1="hello";
	const char * const string2="apple";
	const char * const string3="strcmp";
	const char * const string4="apples";
	printf("strcmp(hello,apple):%d\n",strcmp(string1,string2)); 
	printf("strcmp(hello,strcmp):%d\n",strcmp(string1,string3)); 
	printf("strcmp(strcmp,strcmp):%d\n",strcmp(string3,string3));
	printf("strncmp(apple,apples,5):%d\n",strncmp(string2,string4,5));
	return 0;
} 
} 

在这里插入图片描述

4、strcpy()、strncpy()函数

1、strcpy()函数把字符串从一个数组里复制到另一个数组里,strcpy()函数在字符串运算中的作用等价于赋值运算符。
函数原型 char * __cdecl strcpy(char * __restrict__ _Dest,const char * __restrict__ _Source);,第二个参数指向的字符串被复制到第一个参数指向的数组中。复制的那份字符串被称为目标(target)字符串,最初的字符串被称为源(source)字符串,应注意到它和赋值语句的顺序一样,目标字符串在左边。 要确保目标数组对复制源字符串来说有足够大的空间。
2、strcpy()函数有两个有用的属性,①返回的是第一个参数的值,即一个字符的地址,②第一个参数不需要指向数组的开始,这样就可以只复制数组的一部分。

#include<stdio.h>
#include<string.h>
#define SIZE 40
int main(){
	char *orig = "beast";
	char copy[SIZE]="Be the best that you can be.";
	char *ps;
	
	puts(orig);
	puts(copy);
	ps = strcpy(copy+7,orig);
	puts(copy);
	puts(ps); 
	
	return 0;
} 

在这里插入图片描述

5、memcpy()、memmove()函数

1、可以使用strcpy()strncpy()函数复制字符数组。memcpy()和memmove()函数为复制其他类型的数据提供了类似的便利工具。
函数原型
void * memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _Size) ;
void * memmove(void *_Dst,const void *_Src,size_t _Size) ;
2、两个函数的差别由关键字__restrict__造成。即memcpy()可以假定两个内存区域之间没有重叠;memmove()函数则不作这个假定,因此memmove的复制过程类似于首先将所有字节复制到一个临时缓冲区,然后再复制到最终目的地。如果两个区域存在重叠时使用memcpy(),其行为是不可预知的,因此,使用memcpy()时,必须确保没有重叠区域。这两个函数使用第三个参数来指定要复制的字节数。

//代码选自《C prime Plus》第五版
#include<stdio.h>
#include<string.h>
#define SIZE 10
void show_array(const int ar[],int n);

int main(){
	int values[SIZE] = {1,2,3,4,5,6,7,8,9,10};
	int target[SIZE];
	double curious[SIZE/2] = {1.0, 2.0, 3.0, 4.0, 5.0};
	
	puts("memcpy() used: ");
	puts("values (original data): ");
	
	show_array(values,SIZE);
	memcpy(target,values,SIZE * sizeof(int));
	puts("target (copy of values): ");
	show_array(target,SIZE);
	
	puts("\nUsing memmove() with overlapping ranges: ");
	memmove(values+2,values, 5*sizeof(int));
	puts("values -- elements 0-5 copid to 2-7:");
	show_array(values,SIZE);
	
	puts("\nUsing memcpy() to copy double to int: ");
	memcpy(target,curious,(SIZE/2)*sizeof(double));
	puts("values -- 5 double into 10 int positions:");
	show_array(target,SIZE);
	
	return 0;
} 
void show_array(const int ar[],int n){
	int i;
	for(i=0;i<n;i++){
		printf("%d ",ar[i]);
	}
	putchar('\n');
}

在这里插入图片描述
3、最后一次memcpy()调用把数据从double数组复制到int数组。这表明memcpy()不知道也不关心数据类型;它只是把一些字节从一个位置复制到另一个位置(例如,可以从结构中复制字节到字符型数组)。复制过程中也不进行数据转换。如果使用循环对元素逐个复制,那么在复制过程中会将double类型值转换为int类型值。此时,对字节按原样进行复制,然后程序将把数据作为int类型进行解释。

posted on 2020-05-16 21:24  锅巴味的二进制流  阅读(168)  评论(0)    收藏  举报