Funções de string comumente usadas na linguagem C - o que exatamente está no arquivo de cabeçalho <string.h>?

1. strlen - encontre o comprimento de uma string

1.1 Declaração e uso de strlen

strlen, se tivermos um pouco de inglês básico, não é difícil saber para que serve essa função pelo significado literal, str significa string, o significado de string, len significa comprimento, o significado de comprimento. Ou seja, strlen é uma função que encontra o comprimento de uma string . Usamos o site cplusplus para observar a declaração da função strlen e o significado de cada parâmetro.

Podemos saber que o comprimento da string exigida por strlen é o número de caracteres antes do final da string . Ou seja, assumimos que existe uma string "hello world", então o comprimento da string necessária é o número de todos os caracteres antes de '\0', que é 11. Então o comprimento desta string é retornado pelo valor de retorno , então devemos definir uma variável para receber o valor de retorno se quisermos saber qual é o comprimento da string . Então a parte do parâmetro é, obviamente, o primeiro endereço da string .

1.2 Uso de strlen

#include <stdio.h>
#include <string.h>

int main()
{
	char str1[] = "hello world";
	char* str2 = "hello world";

	int len1 = strlen(str1);//数组名表首元素地址
	int len2 = strlen(str2);//str2 指针变量存放的也是首元素地址

	printf("%d\n", len1);
	printf("%d\n", len2);

	//这种写法也可以输出长度
	//printf("%d\n", strlen(str1));
	//printf("%d\n", strlen(str2));

	return 0;
}

Uma coisa a notar é que o valor de retorno de strlen é do tipo size_t , que é um inteiro sem sinal. Seu significado é que é impossível encontrar números negativos ao encontrar o comprimento, então a memória é otimizada até certo ponto (usar números inteiros com sinal desperdiçará o espaço usado para armazenar números negativos).

 1.3 Implementação de simulação de strlen

Analisamos o princípio do strlen acima, então agora usamos o que aprendemos para " criar " uma função strlen própria.

#include <stdio.h>
#include <assert.h>
unsigned int my_strlen(const char* str)//我们不改变字符串的内容,所以用 const 来进行修饰
{
	assert(str);//避免是一个空指针
	unsigned int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char str1[] = "hello world";
	char* str2 = "hello world";

	int ret1 = my_strlen(str1);
	int ret2 = my_strlen(str2);

	printf("%d\n", ret1);
	printf("%d\n", ret2);

	return 0;
}

2. strcpy - cópia de string

2.1 Declaração e uso de strcpy

Entendemos sua tradução literal, str table string, ou seja, string, cpy table copy, ou seja, copy. Ou seja, a função strcpy é usada para copiar strings . Em seguida, usamos o site cplusplus para observar a declaração de strcpy e o significado de cada parâmetro.

 

Podemos traduzi-lo para conhecer a função de strcpy, copiar a string apontada pelo ponteiro de origem para o array apontado pelo ponteiro de destino, e o conteúdo copiado contém o terminador de string . E o array apontado pelo ponteiro de destino deve ter espaço suficiente para conter o conteúdo após a cópia. 

A partir disso, sabemos que strcpy requer dois parâmetros , um é um array e o outro é uma string. E o espaço da matriz deve ser grande o suficiente. O valor de retorno é o endereço antes de a matriz retornada ser copiada . O significado disso é evitar a perda do conteúdo antes da cópia.

2.2 Uso de strcpy

#include <stdio.h>
#include <string.h>

int main()
{
	char dest[20] = "row your boat";
	char src[] = "hello world";
	strcpy(dest, src);
	printf("%s\n", dest);
	return 0;
}

Este é o uso mais comum do strcpy, só precisamos lembrar de uma coisa: o conteúdo copiado contém '\0' . Ou seja, mesmo que o comprimento da string que copiei não seja tão longo quanto a string original do array, mas inclua '\0', da perspectiva da linguagem C, o conteúdo após '\0' é não contado desde o início. o conteúdo da string .

2.3 Implementação de simulação de strcpy

#include <stdio.h>
#include <assert.h>

char* my_strcpy(char* dest, const char* src)//dest 指向的数组空间是要被改变的,但是 src 指向的字符串不需要改变
{
	assert(dest && src);//防止其中某个是无效指针
	char* ret = dest;
	while (*dest++ = *src++)
		;	//注意 while 循环执行了空语句

	return ret;
}
int main()
{
	char dest[30] = "gently down the stream";
	char src[] = "life is but a dream";

	my_strcpy(dest, src);
	printf("%s\n", dest);
	return 0;
}

3. strcmp - comparação de strings

3.1 Declaração e Uso de strcmp

O mesmo é verdade, podemos entender mais ou menos para que essa função é usada através da tradução literal. str table string, ou seja, string, cmp table compare, ou seja, comparação . Também observamos a declaração desta função e o significado de cada parâmetro através do site cplusplus .

Podemos conhecer o princípio desta função traduzindo-o. O princípio é: a comparação começa a partir do primeiro caractere das duas strings. Se os dois caracteres forem iguais, as duas strings compararão o próximo par de caracteres até que os dois caracteres não sejam iguais e, em seguida, compare o tamanho . Retorna um inteiro menor que 0 se o primeiro caractere for menor que o segundo, 0 se for igual e um inteiro maior que 0 se for maior .

Ambos os argumentos são strings para comparar. Para facilitar o entendimento, entendemos na forma de desenho .

 

 

 3.2 Uso de strcmp

#include <stdio.h>
#include <string.h>

int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret = strcmp(str1, str2);
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

 3.3 Implementação de simulação de strcmp

#include <stdio.h>
#include <assert.h>

int my_strcmp(const char* str1, const char* str2)//两个字符串的内容都不需要修改,用 const 修饰
{
	assert(str1 && str2);//防止是无效指针

	while (*str1 == *str2)//如果相等则进入循环
	{
		if (*str1 == '\0')//*str1 == '\0' 了并且进入循环了,说明两个字符串比较完成了,没有不相等的字符
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;//两个字符的差作为返回值
}
int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret = my_strcmp(str1, str2);
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

4. strcat - Anexar String

4.1 Declaração e Uso de strcat

 Usamos o site cplusplus para observar a declaração de strcat e o significado de cada parâmetro.

Traduza até o uso da função strcat: anexe a string apontada pelo ponteiro de origem ao array apontado pelo ponteiro de destino e há espaço suficiente (tentei anexar à string, mas falhei) e o local anexado é o ponteiro de destino aponta para '\0' da string, ou seja, copie desta posição . Observe que a posição do '\0 ' anexado é a posição do primeiro '\0' .

4.2 Uso de strcat 

#include <stdio.h>
#include <string.h>

int main()
{
	char str1[50] = "row row row your boat,";
	char* str2 = "gently down the stream";
	strcat(str1, str2);
	printf("%s\n", str1);
	return 0;
}

4.3 Implementação de simulação de strcat 

#include <stdio.h>
#include <assert.h>

char* my_strcat(char* dest, const char* src)//src 指向的字符串是不改变内容的,所以用 const 修饰
{
	assert(dest && src);//确保两个指针有效
	char* ret = dest;
	while (*dest)
		dest++;//先找到 dest 指向的数组的第一个 '\0' 的位置
	while (*dest++ = *src++)//拷贝
		;
	return ret;
}
int main()
{
	char str1[50] = "row row row your boat,";
	char* str2 = "gently down the stream";
	my_strcat(str1, str2);
	printf("%s\n", str1);
	return 0;
}

5. strncpy - cópia de string com comprimento limitado

5.1 Declaração e uso do strncpy

A diferença entre strncpy e strcpy é que strncpy tem mais um parâmetro . Esse parâmetro é um inteiro não assinado , ou seja, você pode personalizar quantos bytes de conteúdo copiar . Isso facilita muito nosso uso e melhora a flexibilidade da linguagem C.

5.2 Uso de strncpy

#include <stdio.h>
#include <string.h>

int main()
{
	char str1[20] = "row your boat";
	char str2[] = "hello world";
	strncpy(str1, str2, 3);//我们从 str2 中拷贝三个字节的内容到 str1 去
	printf("%s\n", str1);
	return 0;
}

 

 Podemos ver que a saída é muito estranha, pois quando copiamos apenas três bytes de conteúdo, strncpy não adicionará '\0' no final (ou seja, copiará tanto conteúdo quanto quisermos) , o que é Como resultado, podemos ver o conteúdo do array str1 antes de copiar.

5.3 Implementação de simulação de strncpy

#include <stdio.h>
#include <assert.h>

char* my_strncpy(char* dest, const char* src, unsigned int num)
{
	assert(dest && src);//确保两个指针有效
	char* ret = dest;

	while (num--)//拷贝几个字节
	{
		*dest = *src;
		dest++;
		src++;
	}

	return ret;
}
int main()
{
	char str1[20] = "row your boat";
	char str2[] = "hello world";
	my_strncpy(str1, str2, 3);
	printf("%s\n", str1);
	return 0;
}

6. strncmp - Comparação de strings com comprimento limitado

6.1 Declaração e Uso de strncmp

As funções de strncmp e strcmp são exatamente as mesmas, e o princípio é exatamente o mesmo. Ou seja, se você dominar o strcmp, poderá dominar o strncmp. strncmp tem apenas mais um parâmetro que strcmp , que é um inteiro sem sinal representando bytes. Ou seja, quantos bytes queremos comparar. Podemos observar a declaração desta função e o significado de cada parâmetro através do site cplusplus .

6.2 Uso de strncmp

#include <stdio.h>
#include <string.h>

int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret=strncmp(str1, str2,3);//我们只想比较字符串的前三个字节
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

 

6.3 Implementação de simulação de strncmp

#include <stdio.h>
#include <assert.h>

int my_strncmp(const char* str1, const char* str2, unsigned int num)//两个字符串的内容都不需要变,所以用 const 修饰
{
	assert(str1 && str2);
	while (num-- && *str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret = my_strncmp(str1, str2, 3);//我们只想比较字符串的前三个字节
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

7. strncat - Anexa uma string com comprimento limitado

7.1 Declaração e uso de strncat

Da mesma forma, se você dominar o strcat, poderá dominar o strncat. strncat tem um parâmetro adicional de inteiro sem sinal cujo significado representa o número de bytes. Ou seja, podemos personalizar quantos caracteres queremos anexar ao final de outra string. Podemos observar a declaração de strncat e o significado de cada parâmetro através do site cplusplus .

 

7.2 Uso de strncat

#include <stdio.h>
#include <string.h>

int main()
{
	char str1[50] = "row row row your boat,";
	char str2[] = "gently down the stream";
	strncat(str1, str2, 6);//我们只想追加 6 个字节的字符到 str1 中
	printf("%s\n", str1);
	return 0;
}

 Se prestarmos atenção aqui, encontraremos um problema. Os últimos 6 bytes de caracteres que acrescentamos não contêm '\0' , mas quando a saída final é impressa, parece que recebe um '\0' no final da string. Então isso tem que mencionar as características de strncat, ou seja, strncat adicionará '\0' após a string a ser anexada .

 7.3 Implementação de simulação de strncat

#include <stdio.h>
#include <assert.h>

char* my_strncat(char* dest, const char* src, unsigned int num)//str2 中的字符串不需要被修改,所以用 const 修饰
{
	assert(dest && src);//确保两个指针是有效指针
	char* ret = dest;//记录返回值

	while (*dest)//先找到 dest 指向的 '\0' 的位置
		dest++;
	while (num-- && (*dest++ = *src++) )//拷贝限制的字节数
		;
	*dest = '\0';

	return ret;

}
int main()
{
	char str1[50] = "row row row your boat,";
	char str2[] = "gently down the stream";
	my_strncat(str1, str2, 8);
	printf("%s\n", str1);
	return 0;
}

resumo

Cobrimos uma série de funções de string de comprimento irrestrito e funções de string de comprimento restrito acima. Então, qual é a diferença entre restrito e irrestrito? Em primeiro lugar , a flexibilidade das funções de string irrestritas é relativamente baixa , porque apenas a string inteira pode ser manipulada. No entanto , a flexibilidade da função de string restrita é relativamente alta e o número de caracteres a serem manipulados pode ser personalizado. Além disso, funções de string de comprimento limitado são mais seguras do que funções de string de comprimento irrestrito . Observe que restrito é mais seguro do que irrestrito.

8. strstr - pesquisa de strings

8.1 Declaração e uso de strstr

strstr é literalmente duas strings. Então seu significado é encontrar outra string em uma das strings . Podemos observar a declaração de strstr e o significado de cada parâmetro através do site cplusplus .

Podemos conhecer alguns princípios de strstr traduzindo-o. Se a string 2 for encontrada na string 1, o primeiro endereço da string 2 na string 1 será retornado. Se a string não for encontrada, um ponteiro nulo será retornado .

8.2 Uso de strstr

#include <stdio.h>
#include <string.h>

int main()
{
	char* str1 = "row row row your boat,gently down the stream";
	char* str2 = "row your boat";
	char* ret = strstr(str1, str2);//在 str1 中查找 str2 
	printf("%s\n", ret);
	return 0;
}

Pode-se ver que o valor de retorno é o primeiro endereço da  primeira ocorrência de str2 em str1.

8.3 Implementação simulada de strstr

#include <stdio.h>
#include <assert.h>

char* my_strstr(const char* str1, const char* str2)//不需要改变其内容,用 const 修饰
{
	assert(str1 && str2);//避免是无效指针
	const char* s1 = str1;
	const char* s2 = str2;
	const char* cp = str1;//这个指针变量是至关重要的
	while (*cp)
	{
		s1 = cp;
		s2 = str2;

		//在 str1 中查找 str2 的核心循环
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')//查找完成
			return (char*)cp;

		cp++;
	}
	return NULL;
}
int main()
{
	char* str1 = "row row row your boat,gently down the stream";
	char* str2 = "row your boat";
	char* ret = my_strstr(str1, str2);
	printf("%s\n", ret);
	return 0;
}

Vamos explicar a ideia em detalhes  desenhando uma imagem.

 

 

 

 9. strtok - Fatiar String

9.1 Declaração e utilidade do strtok

Para esta função, precisamos apenas entender o uso básico. Usamos o site cplusplus para observar a declaração de strtok e o significado de cada parâmetro.

Este parágrafo em inglês é muito longo, deixe-me explicar a parte principal: fornecemos dois parâmetros para strtok, um é uma string e o outro é o token a ser cortado. Se o token aparecer na string, a posição será modificada para '\0' e o endereço da string antes que o token seja retornado . Se você quiser passar parâmetros duas vezes, você só precisa passar um ponteiro nulo.

9.2 Uso de strtok

#include <stdio.h>
#include <string.h>

int main()
{
	char* str1 = "row@row~row%your^boat,gently@down~the^stream";
	char* str2 = "@~%^";

	//将 str1 拷贝至 tmp 数组,这样不会丢失 str1 的原始数据
	char tmp[50] = { 0 };
	strcpy(tmp, str1);

	char* ret = NULL;
	for (ret = strtok(tmp, str2); ret != NULL; ret = strtok(NULL, str2))
	{
		printf("%s ", ret);
	}
	return 0;
}

10. strerror - análise de código de erro

10.1 Declaração e uso de strerror

Um ponto que precisamos popularizar é que na linguagem C, quando ocorre um erro de programa, existe uma variável global oculta errno , que é um inteiro, como 0, 1, 2, 3, .... etc. representam diferentes mensagens de erro, e o papel de strerror é traduzir este código de erro . Podemos observar a declaração de strerror e o significado de cada parâmetro  através do site cplusplus .

10.2 Uso de strerror

#include <stdio.h>
#include <string.h>

int main()
{
	FILE* p;
	p = fopen("test.txt", "r");//在我们的工程目录下并没有 test.txt 这个文件
	if (p == NULL)//那么打不开 p 就是一个空指针
	{
		printf("%s\n", strerror(errno));//这里就会解释为什么是空指针的原因
	}
	return 0;
}

 

Acho que você gosta

Origin blog.csdn.net/weixin_59913110/article/details/125657140
Recomendado
Clasificación