文字関数と文字列関数の詳細な説明(シミュレーションの実装を含む)

コンテンツ

1.文字列の長さ関数を見つけます

 1.1 strlen

2.無制限の長さの文字列関数

 2.1 strcpy

 2.2 strcmp

 2.3 strcat

3.長さ制限のある文字列関数

 3.1 strncoy

 3.2 strncmp

 3.3 strncat

 4.文字列ルックアップ

 4.1 strstr

 4.2 strtok

5.メモリ操作機能

 5.1 memcpy

 5.2 memmove

 5.3 memcpy


1.文字列の長さ関数を見つけます

 1.1 strlen

size_t strlen(const char * str);

文字列の長さを見つけるために使用されます。

文字列は「\0」で終わり、strlen関数は文字列の「\ 0」の前に表示される文字数を返します(「\ 0」を除く
)。
パラメータが指す文字列は、「\0」で終わる必要があります。
関数の戻り値はsize_tです。これは文字列の数であり、符号なし整数です。

使用例:

#include<stdio.h>
#include<string.h>
int main() 
{
	char str[] = "duachebdbvla";
	int sz = sizeof(str);
	printf("%d", sz);
	return 0;
}

strlenのモック実装

int my_strlen(const char* str)
{
	assert(str);
	int i = 0;
	while (*str++)
	{
		i++;
	}
	return i;
}


2.無制限の長さの文字列関数

 2.1 strcpy

char * strcpy(char * destination、const char * source);

文字列をコピーするために使用されます。

ソース文字列は「\0」で終わる必要があります。
ソース文字列の「\0」を宛先スペースにコピーします。
宛先スペースは、ソース文字列を保持するのに十分な大きさである必要があります。
ターゲットスペースは変更可能である必要があります。

使用例:

#include<stdio.h>
#include<string.h>
int main() 
{
	char str1[20] = "duachebdbv";
	char str2[20] = "0";
	strcpy(str2, str1);
	printf(str2);
	return 0;
}

strcpyのモック実装:

char* my_strcpy(char*des,const char*src)
{
	char* tmp = des;
	assert(des && src);
	while (*des++ = *src++;)
	{
		;
	}
return tmp;
}

 2.2 strcmp

int strcmp(const char * str1、const char * str2);

文字列のサイズを比較するために使用されます。

最初の文字列が2番目の文字列より大きい場合は、0より大きい数値を返します。
最初の文字列が2番目の文字列と等しい場合は、0を返します。
最初の文字列が2番目の文字列より小さい場合は、0より小さい数値を返します。番号

 

使用例:

#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "asdfghj";
	char str2[20] = "awsdefghjjjk";
	int ret=strcmp(str1, str2);
	if (ret > 0)
	{
		printf("str1>str2");
	}
	else if (ret == 0)
	{
		printf("str1=str2");
	}
	else
	{
		printf("str1<str2");
	}
	return 0;
}

注:strcmpは文字列の長さを比較しませんが、同じ添え字に対応する文字のASCIIコード値を比較するため、文字が同じである場合は、2つが異なるまで次の文字を比較します。このコードは、str1[0]とstr2[0]が両方ともaであるため、次の文字を比較します。str1[1]は's'、str2[1]は'w'であり、sのASCIIコード値は小さいです。 wのASCII値よりも大きいため、0未満の整数が返されます。

モック実装:

int my_strcmp(const char* str1, const char* str2)

{
	assert(*str1 && *str2);
	while (*str1 || *str2)
	{
		if (*str1 == *str2)
		{
			str1++;
			str2++;
		}
		else
		{
			return *str1 - *str2;
		}
	}
	return 0;
}


 2.3 strcat

char * strcat(char * destination、const char * source);

ある文字列を別の文字列の最後にコピーします。

ソース文字列は「\0」で終わる必要があります。
宛先スペースは、ソース文字列の内容を保持するのに十分な大きさである必要があります。
ターゲットスペースは変更可能である必要があります。

使用例:

#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "kajhcjeef";
	char str2[40] = "jdsafbkw";
	strcat(str2, str1);
	printf(str2);
	return 0;
}


モック実装:

char* my_strcat(char* des, const char* scr)
{
	char* tmp = des;
	assert(des && scr);
	while (*des)
	{
		des++;
	}

	while (*des++=*scr++)
	{
		;
	}
	return tmp;
}

上記の3つの関数strcoy、strcmp、strcatの実装は、「\ 0」のときに停止するか、文字列の長さとは関係のない2文字のサイズを比較するだけなので、次のように考えることができます。これらの3つの関数の長さは無制限です。次のstrncoy、strncmp、strncatは長さに関連しています。

3.長さ制限のある文字列関数

 3.1 strncoy

char * strncpy(char * destination、const char * source、size_t num);

 ソース文字列から宛先スペースにnum文字をコピーします。

ソース文字列の長さがnum未満の場合は、ソース文字列をコピーした後、numまでターゲットの末尾に0を追加します。

使用例:

#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "kajhcjeef";
	char str2[40] = "jdsafbkw";
	strncpy(str2, str1,3);
	printf(str2);
	return 0;
}

 モック実装:

char* my_strncpy(char* des, const char* scr, int num)
{
	char* ret = des;
	assert(des && scr);
	while (num--&&*scr&&*des)
	{
		*des++ = *scr++;
	}
	return ret;
}

 3.2 strncmp

int strncmp(const char * str1、const char * str2、size_t num);

2つの文字列の最初のnum文字のサイズを比較するために使用されます。

 2文字が異なる場合、文字列が終了する場合、または比較文字数がnumの場合、比較は停止します。str1の最初のnum文字で構成される文字列が、str2の最初のnum文字で構成される文字列よりも大きい場合、0より大きい整数を返し、等しい場合は0を返し、等しい場合は0未満の整数を返します。未満。

使用例:

#include<string.h>
#include<stdio.h>
int main()
{
	char str1[20] = "jajhcjeef";
	char str2[40] = "jasafbkwn";
	int ret=strncmp(str1, str2, 3);
	printf("%d", ret);
	return 0;
}

モック実装:

int my_strncmp(const char* str1, const char* str2, int num)
{
	assert(str1 && str2);
	while (num--&&(*str1||*str2))
	{
		if (*str1 != *str2)
		{
			return *str1- *str2;
		}
		else
		{
			str1++;
			str2++;
		}
	}
	return 0;
}

 3.3 strncat

char * strncat(char * destination、const char * source、size_t num);

 文字列を追加するために使用されます。

文字列ソースの最初のnum文字を文字列宛先の末尾(「\ 0」で始まる)にコピーします。

使用例:

#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "jajhcjeef";
	char str2[40] = "ja";
	strncat(str2, str1, 6);
	printf(str2);
	return 0;
}

モック実装:

#include<stdio.h>
#include<assert.h>
char* my_strncat(char* des, const char* scr, int num)
{
	char* ret = des;
	assert(des && scr);
	while (*des)
	{
		des++;
	}
	while (num && ((*des++ = *scr++) != '\0'))
	{
		num--;
	}
	if (num == 0)
		*des = '\0';
	return ret;
}

 4.文字列ルックアップ

 4.1 strstr

char * strstr(const char * str1、const char * str2);

文字列str1で文字列str2を見つけます。見つかった場合は、文字列str1で文字列str2と同じフラグメント文字列の開始アドレスを返します。

使用例:

#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = "jajhcjeef";
	char str2[40] = "cj";
	char* tmp = strstr(str1, str2);
	printf("%s",tmp);
	return 0;
}

モック実装:

#include<stdio.h>
//#include<string.h>
#include<assert.h>
char* my_strstr(const char* str, const char* substr)
{
	const char* s1 = str;
	const char* s2 = substr;
	const char* cur = str;

	assert(str && substr);
	if (*substr == '\0')
	{
		return (char*)str;
	}
	while (*cur)
	{
		s1 = cur;
		s2 = substr;
		while (*s1 &&  *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return (char*)cur;

		cur++;
	}
	return NULL;
}

 4.2 strtok

char * strtok(char * str、const char * sep);

ユーザー指定の区切り文字に従って文字列を分割するために使用されます。
最初の引数は、sep文字列内の1つ以上の区切り文字で区切られた0個以上のトークンを含む文字列を指定します
2番目のパラメーターsepは、区切り文字として使用される文字のセットを定義する文字列です。
strtok関数は、str内の次のトークンを検索し、\ 0で終了して、このトークンへのポインターを返します。(注:
strtok関数は操作される文字列を変更するため、strtok関数によってセグメント化された文字列は通常、一時コピーの内容であり、
変更できます。)
strtok関数の最初のパラメーターがNULLでない場合、関数は次のように検出します。 str strtok関数の最初のトークンは
、文字列内の位置を保存します。strtok関数の最初の引数はNULLであり、関数は同じ文字列内の保存された位置から開始し、次のトークン
を探し文字列にトークンがもうない場合は、NULLポインタが返されます。

使用例:

#include<stdio.h>
#include<string.h>
int main()
{
	char str1[50] = "zhouling#123.b@uo";
	const char sep[10] = "#.@";
	char arr[50];
	char* ch = NULL;
	strcpy(arr, str1);
	for (ch = strtok(arr, sep);ch != NULL; ch = strtok(NULL, sep))
	{
		printf("%s\n", ch);

	}
	return 0;
}

5.メモリ操作機能

 5.1 memcpy

void * memcpy( void * dest const void * src size_t count );

関数memcpyは、numバイトのデータをソースの場所から宛先のメモリの場所に逆方向にコピーします。
この関数は、「\0」に遭遇しても停止しません。この関数はstrcmpにいくぶん似ていますが、この関数は整数または他のタイプのデータをコピーできます。
ソースと宛先の間に重複がある場合、コピーの結果は未定義です。

例1を使用します:

#include<stdio.h>
int main()
{
	char str1[] = "zhouling";
	char str2[] = "mlanvkml";
	int arr1[4] = { 1,2,3,4 };
	int arr2[4] = { 5,6,7,8 };
	int i = 0;
	char*str = memcpy(str2, str1, sizeof(str1[0]) * 2 );
	int* arr = memcpy(arr1, arr2, sizeof(arr1[0]) * 2);
	for (i = 0; i < 4; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	printf("%s", str);
	return 0;
}


 例2を使用します。

#include<stdio.h>
#include<string.h>
struct PeoPle
{
	char name[20];
	int age;
}People1,People2;
int main()
{
	char myname[] = "zhouling";
	People1.age = 18;
	memcpy(People1.name, myname, sizeof(myname)+1);
	memcpy(&People2, &People1, sizeof(People1));
	printf("People2:%s %d", People2.name, People2.age);
	return 0;
}

 

 

モック実装:

void* my_memcpy(void* dst, const void* src, size_t count)

{

    void* ret = dst;

    assert(dst&&src);

    while (count--) 
    {

        *(char*)dst = *(char*)src;

        dst = (char*)dst + 1;

        src = (char*)src + 1;
    
    }

    return ret;
}

 5.2 memmove

void * memmove(void * destination、const void * source、size_t num);

関数は基本的にmemcpyと同じですが、memcpyとの違いは、memmove関数によって処理されるソースメモリブロックとターゲットメモリブロックがオーバーラップする可能性があることです。
ソーススペースとターゲットスペースが重なっている場合は、memmove関数を使用して処理するのが最適です。

使用例:

#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "I don't love you and you like.......me";
	memmove(str + 25, str + 2,11);
	puts(str);
	return 0;
}

 モック実装:

void * my_memmove(void* des, const void* scr, int num)
{
	void* ret = des;
	assert(des && scr);
	while (num--)
	{
		if (des < scr)
		{
			*((char*)des)++ = *((char*)scr)++;
		}
		else
		{
			*((char*)(des)+num) = *((char*)(scr)+num);
		}
	}
	return ret;

}

 5.3 memcpy

int memcmp( const void * buf1 const void * buf2 size_t count );

ptr1ポインターとptr2ポインターから始まるnumバイトを比較します。前者が後者よりも大きい場合は、0より大きい整数が返されます。それ以外の場合は、0未満の整数が返され、等しい場合は0が返されます。

 使用例:

#include <stdio.h>
#include <string.h>
int main()
{
	char buffer1[] = "zhouzhou";
	char buffer2[] = "zhdhZhou";
	int n;
	n = memcmp(buffer1, buffer2, 2);
	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;
}

モック実装:

int my_memcmp(const void* buf1, const void* buf2, size_t count)
{
	void* tmp1 = buf1;
	void* tmp2 = buf2;
	assert(buf1 && buf2);
	while (count--)
	{
		if (*((char*)tmp1) != *((char*)tmp2))
		{
			return *((char*)tmp1) - *((char*)tmp2);
		}
		((char*)tmp1)++;
		((char*)tmp2)++;
	}
}

了解しました。これで、今日の学習ノートの共有は終了です。ここに表示されている場合は、いいねを付けてください。

 

おすすめ

転載: blog.csdn.net/m0_63039919/article/details/123138585