文字関数と文字列関数strcpystrcmp strstr memmove

ヒント:記事を書いた後、目次を自動的に生成できます。生成方法については、右側のヘルプドキュメントを参照してください。


序文

C言語での文字と文字列の処理は非常に頻繁ですが、C言語自体には文字列型がなく、文字列は通常、定数文字列または文字配列に配置されます。文字列定数は、それを変更しない文字列関数に適しています。

1つ、strlen

この関数は、文字列の「\ 0」の前に表示される文字数を返します。パラメータが指す文字列は、「\ 0」で終わる必要があります。シミュレーションの実装は次のとおりです。

#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现strlen
int my_strlen(const char *string){
    
    
	assert(string != NULL);
	int count = 0;
	const char *p = string;
	while (*p++ != '\0'){
    
    
		count++;
	}
	return count;
}
void main(){
    
    
	char *str = "abcdef";
	printf("%d\n", my_strlen(str));
}

2、strcpy

最初の文字列の値を最初の文字列に割り当てるには、2つのパラメータがあります。ソース文字列は「\ 0」で終わる必要があり、ソース文字列の「\ 0」はターゲットスペースにコピーされます。ターゲットスペースは次のようになります。ソース文字列を格納できるようにするのに十分な大きさ。このモードは次のように実装されます。

#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现strcpy
char * my_strcpy(void *dest, const void *src)
{
    
    
	assert(dest!=NULL && src!=NULL);
	char *pdest = (char *)dest;
	const char *psrc = (const char *)src;
	while (*psrc != '\0'){
    
    
		*pdest++ = *psrc++;
	}
	pdest= '\0';
	return dest;
}

void main(){
    
    
	char *str = "abcdse";
	char arr[20] = {
    
    0};
	printf("%s\n", my_strcpy(arr, str));
}

3、strcmp

比較関数、文字列のサイズを比較するために、この関数は各文字列の最初の文字の比較を開始します。それらが等しい場合、文字が異なるまで、または終了するヌル文字に
達するまで、以下と比較し続けます(ここではASCII比較を使用していますが、すべての文字のASCIIコードが合計されず、全体としてカウントされることに注意してください。最初はそう思いますが、strcmpは文字を1つずつ比較します。結果が出ると、すぐに終了して戻ります)

#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现strcmp
int my_strcmp(const char *string1, const char *string2)
{
    
    
	assert(string1 != NULL && string2 != NULL);
	const char *ps1 = string1;
	const char *ps2 = string2;

	while (*ps1 != '\0' && *ps2 != '\0')
	{
    
    
		if (*ps1 > *ps2)
			return 1;
		else if (*ps1 < *ps2)
			return -1;
		ps1++;
		ps2++;
	}

	if (*ps1 != '\0')
		return 1;
	if (*ps2 != '\0')
		return -1;
	return 0;
}

void main()
{
    
    
	char *str1 = "Hello";
	char *str2 = "HelloAAA";
	int ret = my_strcmp(str1, str2); //<0 ==0 >0
	if (ret == 0)
		printf("str1 == str2");
	else if (ret < 0)
		printf("str1 < str2");
	else
		printf("str1 > str2");
}

4、strcat

ソース文字と終了ヌル文字をターゲットに「追加」します。ソース文字列は「\ 0」で終わる必要があり、ターゲットスペースは変更可能である必要があり、スペースは十分な大きさである必要があります。

#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现strcat
char *my_strcat(void *dest, const void *src)
{
    
    
	assert(dest != NULL &&src != NULL);
	char *pdest = (char *)dest;	
    char *psrc = (const char *)src;
	while (*pdest){
    
    
		pdest++;
	}
	while ((*pdest++ = *psrc++));
	return dest;
}

void main(){
    
    
	char *str = "bcdef";
	char ar[20] = {
    
    'a'};
	printf("%s\n", my_strcat(ar, str));
}

ファイブ、strstr

str1で最初に出現するstr2へのポインタを返します。str2がstr1の一部でない場合は、nullポインタを返します。

#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现strstr
char *my_strstr(const char*src, const char*dest)
{
    
    
	assert(dest != NULL &&src != NULL);
	char *pdest = (const char *)dest;
	char *psrc = (const char *)src;
	char *s1 = (const char *)src;
	if (*pdest == '\0')
		return NULL;
	while (*psrc){
    
    
		psrc = s1;
		while (*pdest && *psrc && (*pdest == *psrc)){
    
    
			pdest++;
			psrc++;
		}
		if (*pdest == '\0')
			return s1;
		s1++;
	}
	return NULL;
}

void main(){
    
    
	char str[20] = "abcdef";
	char ar[20] = "bc";
	printf("%s\n", my_strstr(str, ar));
}

6、memmove

memcpy関数と同様に、ソースメモリブロックとターゲットメモリブロックの重なりを処理できる点が異なります。

#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现memmove
void* my_memmove(void *dest, const void *src, size_t count)
{
    
    
	assert(dest != NULL && src != NULL);
	char *pdest = (char *)dest;
	const char *psrc = (const char *)src;

	if (psrc >= pdest || pdest >= psrc + count)
	{
    
    
		while (count-- > 0)
		{
    
    
			*pdest++ = *psrc++;
		}
	}
	else
	{
    
    
		//存在内存重叠
		psrc = psrc + count - 1;
		pdest = pdest + count - 1;
		while (count-- > 0)
		{
    
    
			*pdest-- = *psrc--;
		}
	}

	return dest;
}
void main()
{
    
    
	char str[20] = "abcdefghijk";
	char st[20]="acsxd";
	printf("str = %s\n", str);
	memmove(st, str, 4);
	//my_memmove(str + 2, str, 4);
	printf("str = %s\n", st);
	printf("str = %s\n", str);
}

重なりを決定する関数をキャンセルすると、memcpy関数と同じになります。したがって、ここではmemcpy関数を確認しません。

総括する

これらの関数に加えて、strncpy、strncat、strncmpなどの関数があります。ソースとターゲットに加えて、これらの関数のパラメーターは長さであるため、条件を変更することで、シミュレーションと実装が比較的簡単です。 whileループの成功は、この長さに関連しています(count–> 0)。

おすすめ

転載: blog.csdn.net/weixin_45070922/article/details/110008936