字符串的比较和拷贝的函数是啥

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串的比较和拷贝的函数是啥相关的知识,希望对你有一定的参考价值。

字符串的比较和拷贝的函数是什么

字符串比较函数是strcmp(str1,str2);拷贝函数是strcpy(str1,str2)。

字符串在存储上类似字符数组,所以它每一位的单个元素都是可以提取的,如s=“abcdefghij”,则s[1]=“b”,s[9]="j",而字符串的零位正是它的长度;

如s[0]=10(※上述功能Ansistring没有。),这可以提供很多方便,如高精度运算时每一位都可以转化为数字存入数组。

1、字符串定位函数:InStr,InStrRev,InStrB

2、字符串截取函数:Mid,Right,Left

3、字符串替换函数:Replace

4、字符串分割函数:Split

5、字符串格式化输出:Format

扩展资料:

字符串可以用“.”(点)运算符连接。注意这里不能用“+”(加)运算符。更多信息参见字符串运算符。有很多实用函数来改变字符串。

普通函数见字符串函数一节,高级搜索和替换见正则表达式函数(两种风格:Perl 和 POSIX 扩展)。还有 URL 字符串函数,以及加密/解密字符串的函数(mcrypt 和 mhash)。最后,如果还是找不到想要的函数,参见字符类型函数。

参考技术A 字符串比较是strcmp(str1,str2),拷贝是strcpy(str1,str2)。使用这两个函数前要先包含头文件,#include <string.h>.不知道对你有没有帮助? 参考技术B 1、strcpy()是字符串函数,用来进行字符串的复制;
2、strcpy(x,y)会把x中的数据覆盖掉,使用这个函数时最好保证y的长度在x的长度范围中,要不可能会出错!
如果你不想把x中的数据覆盖掉,你可以使用srtcat()函数
3、注意,头文件中必须包括#include<string.h>

strcmp函数 strcmp函数是比较两个字符串的大小,返回比较的结果。一般形式是: i=strcmp(字符串,字符串);其中,字符串1、字符串2均可为字符串常量或变量;i 是用于存放比较结果的整型变量。比较结果是这样规定的: 1:字符串1小于字符串2,strcmp函数返回一个负值;2:字符串1等于字符串2,strcmp函数返回零;③字符串1大于字符串2,strcmp函数返回一个正值;本回答被提问者采纳
参考技术C strcpy
strcmp
#include<string.h>
参考技术D 比较 strcmp(s1, s2)
拷贝 strcpy(s1, s2)

C语言进阶:字符串和内存函数

字符串和内存函数

C语言本身并无字符串类型但其对字符串的操作却较为频繁。本章节介绍这些函数的用法和实现。

字符串函数

字符串求长函数 strlen
函数声明
size_t strlen ( const char* string );
Return Value
This function returns the number of characters in string, excluding the terminal NULL. No return value is reserved to indicate an error.

Parameter
string - Null-terminated string
函数用法
  • '\\0'为字符串结束标志,故strlen函数计算\\0之前的字符个数。

  • 参数是字符串的地址,而字符串必须为以\\0结尾的字符串。

//1.
char arr1[] = "abcd";
printf("%d\\n", strlen(arr1));//4
//2.
char arr2[] = { 'a','b','c','d' };
printf("%d\\n", strlen(arr2));//随机值
//3.
int a = 10;
printf("%d\\n", strlen(a));//报错
  1. 传参过去的是以\\0结尾的字符串地址,满足strlen的要求。
  2. 传参的虽然是字符串的地址但未以\\0结尾,故strlen会一直找下去,直至找到\\0
  3. 传参根本不是地址,该整型会被strlen当作地址看待,故访问到0x0A地址处的非法内存。如图:

  • strlen函数返回类型为size_t,注意无符号数的用法。
size_t ret = strlen("abcdef");
printf("%u\\n", ret);

无符号数接收,以无符号的形式打印。不要使用无符号数运算结果比大小:

 if (strlen("abc") - strlen("abcdef") < 0) {
    printf("hehe\\n");
}
else {
    printf("haha\\n");
}

无符号数的运算结果被整形提升为无符号数,故二者相减所得被视为无符号数是不会小于零的。

模拟实现
//1.计数器
size_t my_strlen(const char* str) {
	assert(str);
	size_t count = 0;
	while (*str) {
		count++;
		str++;
	}
	return count;
}
//2.指针相减
size_t my_strlen(const char* str) {
	assert(str);
	char* begin = str;
	while (*str) {
		str++;
	}
	return str - begin;
}
//3.递归
size_t my_strlen(const char* str) {
	assert(str);
    if (*str) {
		return 1 + my_strlen(str + 1);
	}
	else {
		return 0;
	}
}

 

长度不受限制的字符串函数

字符串函数分为长度不受限制的字符串函数和长度受限制的字符串函数。先介绍长度不受限制的字符串函数。

字符串拷贝函数 strcpy
函数声明
char* strcpy ( char* strDestination, const char* strSource );
Return Value
This function returns the destination string. No return value is reserved to indicate an error.

Parameters
1. strDestination - Destination string
2. strSource - Null-terminated source string

Remarks
1The strcpy function copies the string pointed by strSource to the array pointed by strDestination,including the terminating null character. 
No overflow checking(溢出检查) is performed when strings are copied. The behavior of strcpy is undefined(未定义的) if the source and destination strings overlap(重叠).

strcpy将源字符串的内容(包括\\0)依次拷贝到目标空间。

函数用法
  • 源字符串以'\\0'结尾,且strcpy会将源字符串中\\0也拷贝到目标空间。

拷贝时会把\\0也一同拷贝。若源字符串中有\\0,其后的元素自然是不会被拷贝的,因为在读取时也就把\\0作为结束标志。

若源字符串不以\\0结尾,则strcpy会向后一直访问到非法内存。

  • 目标空间可修改且足够大,确保能够且足以存放源字符串。
//1.
char arr1[] = "xxx";//目标空间不够大
char arr2[] = "abcdef";
//.2
const char arr1[] = "xxxxxxxxxx";//目标空间不可修改
char arr2[] = "abcdef";

strcpy(arr1, arr2);

以上两种情况同样是需要避免的。

strcpyvs2019环境下使用会报出不安全的警告,该函数在拷贝前不会去检查是否会发生数组越界,警告也是正常的。但作为合格的程序员,我们有义务排除风险。

模拟实现
char* my_strcpy(char* dest, const char* src) {
	assert(dest && src);
    char* begin = dest;
	while (*dest++ = *src++) {
		;
	}
	return begin;
}

 

字符串追加函数 strcat
函数声明
char* strcat ( char* strDestination, const char* strSource );
Return Value
This function returns the destination string. No return value is reserved to indicate an error.

Parameters
1. strDestination - Null-terminated destination string
2. strSource - Null-terminated source string

Remarks
The strcat function appends strSource to strDestination and terminates the resulting string with a null character.
The initial character of strSource overwrites the terminating null character of strDestination. 
No overflow checking is performed when strings are copied or appended. The behavior of strcat is undefined if the source and destination strings overlap.

strcat将源字符串包括\\0,追加到目标字符串的结尾并覆盖掉目标空间的\\0

函数用法
  • 源字符串必须以'\\0'结尾,strcat会将\\0追加到目标空间的末尾作字符串结束标志。

该例子同样是源字符串不以\\0结尾,从而访问到非法空间。

  • 目标空间必须足够大且可修改,确保能够且足以追加字符串。

目标字符串以初始化内容确定大小,这种初始化的方式显然是不能追加字符串的。同样目标字符串不可加const修饰。strcat在调用时仍然不作溢出检查,只有到溢出后才报错。

模拟实现
char* my_strcat (char* dest, const char* src) {
	assert(dest && src);
	char* begin = dest;
	//移到末尾
	while (*dest) {
		dest++;
	}
	//追加
	while (*dest++ = *src++) {
		;
	}
	return begin;
}

下面三种while循环的特点:

//1.
while (*dest++) {
	;
}
//2.
while (*dest) {
    dest++;
}
//3.
while (*dest++ = *src++) {
    ;
}
  • 第一种和第二种的区别在于,第一种指针解引用后就++,第二种指针解引用后判断为真才能++ 。故第一种解引用的次数和++的次数是相等的,当指针指向\\0时也要++访问下一个元素。而第二种为真后++,指向\\0时便停留在\\0处 。
  • 将赋值运算*dest=*src放入while循环内,当src指向\\0时也要赋值给dest,在这之后判断整个表达式为假,退出循环。

 

字符串比较函数 strcmp
函数声明
int strcmp ( const char* string1, const char* string2 );
Return Value
The return value for this function indicates the relation of string1 to string2.
+-------+------------------------------------+
| Value | Relationship of string1 to string2 |
+-------+------------------------------------+
|  <0   |    string1 less than string2       |
|   0   |    string1 identical to string2    |
|  >0   |    string1 greater than string2    |
+-------+------------------------------------+

Parameters
1. string1, string2
2. Null-terminated strings to compare

Remarks
The strcmp function compares string1 and string2, what starts comparing the first character of each string, if are equal, continuing with the follows until the differ or a null-character is reached, and returns a value indicating their relationship.  

strcmp遍历比较两个字符串对应位置的字符的ASCII码值是否相等。

函数用法
  • 函数的返回值
    1. 字符串1小于字符串2时,返回小于0的数字
    2. 字符串1等于字符串2时,返回0
    3. 字符串1大于字符串2时,返回大于0的数字
  • 二者都要以\\0作为字符串的结尾,否则仍会越界访问。
模拟实现
int my_strcmp(const char* str1, const char* str2) {
	assert(str1 && str2);
	while (*str1 == *str2) {
		if (*str1 == '\\0') {
			return 0;
		}
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

都是\\0就返回0,不是就都++,直到不等时返回二者之差。

不安全是长度不受限制的字符串函数的通病,因为这些函数在调用时一直向后遍历访问且不做溢出检查直到程序出错才被迫停止。所以C语言还内置了相对安全的长度受限制的字符串函数,以及更加通用的内存函数。

 

长度受限制的字符串函数

字符串拷贝函数 strncpy
函数声明
char* strncpy ( char* strDest, const char* strSource, size_t count );
Return Value
This function returns strDest. No return value is reserved to indicate an error.

Parameters
1. strDest - Destination string
2. strSource - Source string
3. count - Number of characters to be copied

Remarks
The strncpy function copies the initial count characters of strSource to strDest and returns strDest.
If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. 
If count is greater than the length of strSource, the destination string is padded(填充) with null characters up to length count. 
The behavior of strncpy is undefined if the source and destination strings overlap.

strcpy函数从源字符串拷贝count个字符到目标字符串,若count大于源字符串长度则以\\0填充。

函数用法
  • 目标字符串可修改且足够大
  • count小于源字符串个数则不追加\\0,若大于源字符串个数则以\\0填充到count个字符。

模拟实现
char* my_strncpy(char* dest, const char* src, size_t count) {
	assert(dest && src);
	char* begin = dest;
    //字符串拷贝到count个或遇到\\0
    while (count-- && (*dest++ = *src++)) {
		;
	}
    //count>源字符串长度,末尾补零
    while (count) {
		*dest++ = '\\0';
		count--;
	}
	return begin;
}
int main()
{
	char arr1[10] = "abcdef";
	char arr2[] = "xxx";
	
	my_strncpy(arr1, arr2, 5);
	printf("%s\\n", arr1);
 	return 0;
}

下列三种是进行字符串拷贝时的代码。当count小于源字符串个数时三者都没问题,但当count大于源字符串个数时,三者的情况却是不一样的。

//1.
while (count && src) {
    *dest++ = *src++;
    count--;
}
//2.
while (count && (*dest++ = *src++)) {
    count--;
}
//3.
while (count-- && (*dest++ = *src++)) {
    ;
}
  1. 当指向源字符串的指针遇到\\0时,不进行赋值和++也不进行count--操作。

赋值赋了3次,count也减了3次。此时count为2,随后追加了2个\\0

  1. 指针指向\\0时执行赋值操作后,赋值表达式为假,结束循环。

由于赋值操作放在循环的判断部分,故赋值执行了4次,而count减了3次。

即源字符串末尾\\0也被拷贝了过去,但count仍为2,所以最后还要追加2个\\0。但这样就改变了6个字符,显然是错误的。

  1. 将第二种代码稍作修改,将count--的操作也放入判断部分,这样就避免了上述问题。

如果循环条件只有循环变量count大小的判断,则进步条件放在判断部分还是循环体内没有影响。

 

字符串追加函数 strncat
函数声明
char* strncat ( char* strDest, const char* strSource, size_t count );
Return Value
This function returns a pointer to the destination string. No return value is reserved to indicate an error.

Parameters
1. strDest - Null-terminated destination string
2. strSource - Null-terminated source string
3. count - Number of characters to append

Remarks
The strncat function appends, at most, the first count characters of strSource to strDest. The initial character of strSource overwrites the terminating null character of strDest. 
If a null character appears in strSource before count characters are appended, strncat appends all characters from strSource, up to the null character. 
If count is greater than the length of strSource, the length of strSource is used in place of count. The resulting string is terminated with a null character. 
If copying takes place between strings that overlap, the behavior is undefined.

在目标字符串末尾追加count个源字符串的字符,结尾默认添加\\0

函数用法
  • 追加到目标字符串末尾默认补'\\0'count超出源字符串个数不在追加。

模拟实现
char* my_strncat(char* dest, const char* src, size_t count) {
	assert(dest && src);
	char* begin = dest;
	//1. 来到目标字符串末尾
	while (*dest) {
		dest++;
	}
	//2. 追加
	while (count && (*dest++ = *src++)) {
		count--;
	}
	//3. count小于字符个数补0
	if (count == 0) {
		*dest = '\\0';
	}
	return begin;
}

 

字符串比较函数 stnrcmp
函数声明
int strncmp ( const char* string1, const char* string2, size_t count );
Return Value
The return value for each of these functions indicates the relation of string1 to string2.
+-------+------------------------------------+
| Value | Relationship of string1 to string2 |
+-------+------------------------------------+
|  <0   |    string1 less than string2       |
|   0   |    string1 identical to string2    |
|  >0   |    string1 greater than string2    |
+-------+------------------------------------+

Parameters
1. string1, string2 - Null-terminated strings to compare.
2. count - Number of characters to compare

Remarks
The strncmp function lexicographically compares, at most, the first count characters in string1 and string2 and returns a value indicating the relationship between the substrings.

比较两个字符串的前count个字符,并返回相关的数值。

模拟实现
int my_strncmp(const char* str1, const char* str2, size_t count) {
	assert(str1 && str2);
    while (count-- && (*str1 == *str2)) {
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

 

字符串查找函数 strstr
函数声明
char* strstr ( const char* string, const char* strCharSet );
Return Value
This function returns a pointer to the first occurrence of strCharSet in string, or NULL if strCharSet does not appear in string. 
If strCharSet points to a string of zero length, the function returns string.

Parameters
1. string - Null-terminated string to search
2. strCharSet - Null-terminated string to search for

Remarks
The strstr function returns a pointer to the first occurrence of strCharSet in string. The search does not include terminating null characters. 

查找子字符串在目标字符串中首次出现的位置,有则返回之起始位置,无则返回空指针。

模拟实现
char* my_strstr(const char* str, const char* set) {
	assert(str && set);
	char* s1 = str;
	char* s2 = set;
	while (*s1) {
		//归位
		str = s1; 
		set = s2;
		//防止s1=s1=\\0
		while ((*str && *set) && (*str == *set)) {
			str++;
			set++;
		}		
		//判断
		if (*set == '\\0') {
			return s1;
		}
		//进位
		s1++;
	}
	return NULL;
}

s1s2存放strset每次归位时的位置,以便匹配错误时返回重新开始。

  • 特殊情况set="\\0"时,\\0是任意字符串的子字符串,即无任何字符的字符串是任意字符串的子字符串。所以返回母字符串
  • 一次匹配错误时,str和set要归位初始位置,即str=++s1;set=s2;要放在判断部分的后面。(set=s2下次循环再执行就相当于在后面)

KMP算法专门针对字符串匹配和查找这种功能。

 

字符串分割函数 strtok
函数声明
char* strtok ( char* strToken, const char* strDelimit );
Return Value
This function returns a pointer to the next token found in strToken. They return NULL when no more tokens are found. Each call modifies(修改) strToken by substituting(替换) a NULL character for each delimiter(分割符) that is encountered(遇到).

Parameters
1. strToken - String containing token(s)(标记)
2. strDelimit -String Set of delimiter characters

Remarks
The strtok function finds the next token in strToken. The set of characters in strDelimit specifies(指定) possible delimiters of the token to be found in strToken on the current call.

strtok函数通过以\\0替换分隔符的方式修改需分割的字符串,并返回该标记的地址。

函数用法

如字符串"192.168.11.1"或者"yourfriendyo@ms.com"二者字符串都有相似之处,即整个字符串由分隔符.,@分割。如果需要得到分隔符所分割出的每个小字符串,则可以用strtok函数切分。

  • 参数strDelimit是所有分隔符所组成字符串,参数strToken是由一个或多个分隔符和标记组成的字符串。

类似于.,@称为分隔符,而分隔符所分割出的子字符串如192,com被称作标记。

  • strstr将标记以\\0结尾且返回指向该标记的指针。故被操作字符串会发生修改,故一般使用临时拷贝的内容。

  • 首个参数传入字符串地址时,找到其首个标记。随后保存分隔符的位置,此时仅需传入NULL则可访问该字符串的下一个标记。

第一次调用传入需分割字符串的地址,函数保存首个标记后的分隔符被\\0替换的位置。之后的调用就无需在传入地址。当访问到最后一个标记时,函数 返回NULL

char arr[] = "www.yourfriendyo.top";
printf("%s\\n", strtok(arr2, "."));
printf("%s\\n", strtok(NULL, "."));
printf("%s\\n", strtok(NULL, "."));
int main()
{
	char arr[] = "yourfriendyo@ms.com";
	char* sep = "@.";
	for (char* i = strtok(arr, sep); i != NULL; i = strtok(NULL, sep)) {
		printf("%s\\n", i);
	}
	return 0;
}

 

字符串报错函数 strerror
函数声明
char *strerror ( int errnum );
Return Value
strerror returns a pointer to the error-message string. Subsequent calls to strerror can overwrite the string.

Parameters
1. errnum - Error number
2. strErrMsg - User-supplied message

Remarks
The strerror function maps errnum to an error-message string, returning a pointer to the string. strerror  can't actually prints the message: For that, you need to call an output function such as printf.
If strErrMsg is passed as NULL, strerror returns a pointer to a string containing the system error message. 

strerror返回内置错误码所对应的错误信息的字符串地址。

函数用法
printf("%s\\n", strerror(40));//Function not implemented
printf(以上是关于字符串的比较和拷贝的函数是啥的主要内容,如果未能解决你的问题,请参考以下文章

玩转C语言库函数。包含strlenstrcpystrcmpstrcatmemcmpmemmovestrstr等等常用的库函数

玩转C语言库函数。包含strlenstrcpystrcmpstrcatmemcmpmemmovestrstr等等常用的库函数

Python 列表生成式,函数,字符串,文件操作,生成器

字符串函数(strcpy字符串拷,strcmp字符串比较,strstr字符串查找,strDelChar字符串删除字符,strrev字符串反序,memmove拷贝内存块,strlen字符串长度)(示例代

C语言进阶:字符串和内存函数

输入一个介于0到5之间的,字符串是啥意思?