[C Avanzado] Función de caracteres y función de cadena

contenido

1, estrell

     1.1 Tres implementaciones de simulación

2. Funciones de cadena con longitud ilimitada

      2.1, strcpy

               2.1.1 Implementación de la simulación

      2.2, transmisión

               2.2.1 Implementación de la simulación

      2.3, strcmp

               2.3.1 Implementación de la simulación

3. Funciones de cadena con longitud limitada

      3.1, strncpy

               3.1.1 Implementación de la simulación

      3.2, strncat

               3.2.1 Implementación de la simulación

      3.3, strncmp

               3.3.1 Implementación de la simulación

4. Búsqueda de cadenas

      4.1, strstr

               4.1.1 Implementación de la simulación

      4.2, strtok

5. Informe de mensajes de error

      5.1, terror

6. Operación de caracteres

      6.1, función de clasificación de caracteres

      6.2, conversión de caracteres

7. Función de operación de memoria

      7.1, memcpy

               7.1.1 Implementación de la simulación

      7.2, movimiento de memoria

               7.2.1 Implementación de la simulación

      7.3, conjunto de memoria

      7.4, memcmp


1, estrell

  • Función: encontrar la longitud de la cadena
#include<stdio.h>
#include<string.h>
int main()
{
	printf("%d\n", strlen("abcdef"));//6
	return 0;
}
  • Precauciones:
  1. La cadena termina con '\0' y la función strlen devuelve el número de caracteres (excluyendo '\0') que aparecen antes de '\0' en la cadena.
  2. La cadena a la que apunta el parámetro debe terminar con '\0'.
  3. Tenga en cuenta que el valor de retorno de la función es size_t, que no está firmado (propenso a errores)

Nota:

#include<stdio.h>
#include<string.h>
int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
		printf(">");
	else
		printf("<=");
	return 0;
}

  • Analizar gramaticalmente:
size_t strlen ( const char * str );
  1. El tipo de retorno de la función de biblioteca strlen es size_t, que es un número sin signo.
  2. sizeof -- operador -- calcula el tamaño. La esencia de size_t: unsigned int, size_t está especialmente diseñado para el tipo de retorno de sizeof. Dado que size_t es un entero sin signo, el valor siempre es > 0
  3. En el código anterior, la longitud de abc es 3 y la longitud de abcdef es 6. El valor de 3-6 es para tratar -3 como un número sin signo, y el complemento convertido al código original y luego impreso es muy número positivo grande. Entonces>

     1.1 Tres implementaciones de simulación

  • Método 1: método de contador:
#include <stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{
	assert(str);
	int count = 0;
	while (*str != '\0')//判断字符串是否结束
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	int len = my_strlen("abcdef");
	printf("%d\n", len);  // 6
	return 0;
}
  • Método 2: método recursivo:
#include<stdio.h>
int my_strlen(char* s)
{
	if (*s == '\0')
		return 0;
	else
		return 1 + my_strlen(s + 1);
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d\n", len);  // 6
	return 0;
}
  • Método 3: Puntero-Puntero:
#include<stdio.h>
int my_strlen(char* s)
{
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);  //6
	printf("%d\n", len);
	return 0;
}

2. Funciones de cadena con longitud ilimitada

2.1, strcpy

  • Función: copiar cadena
#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdef";
	//char arr1[] = { 'a','b','c','e','f','\0' };
	char arr2[20] = "xxxxxxxxxxx";
	strcpy(arr2, arr1);
	//此时arr2="abcdef\0xxxx"
	printf("%s\n", arr2); // abcdef
	return 0;
}

El primer parámetro de la función strcpy es el destino arr2 y el segundo parámetro es la cadena de datos de origen arr1. Copie el contenido de arr1 a arr2.

  • Precauciones:
  1. La cadena de origen debe terminar con '\0'.
  2. Copiará '\0' en la cadena de origen al espacio de destino.
  3. El espacio de destino debe ser lo suficientemente grande para contener la cadena de origen.
  4. El espacio de destino debe ser mutable.

2.1.1 Implementación de la simulación

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'};
	char arr2[20] = "xxxxxxxxxxxx";
	my_strcpy(arr2, arr1);
	printf("%s\n", arr2); // abcdef
	return 0;
}

2.2, transmisión

  • Función: cadena de conexión
#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[30] = "hello";
	char arr2[] = "world";// {'w', 'o', 'r', 'l', 'd', '\0'};
	strcat(arr1, arr2);
	printf("%s\n", arr1);// helloworld
	return 0;
}

Agregue los caracteres de arr2 a arr1.

  • Precauciones:
  1. La cadena de origen debe terminar con '\0'.
  2. El espacio de destino debe ser lo suficientemente grande para albergar el contenido de la cadena de origen.
  3. El espacio de destino debe ser modificable.

2.2.1 Implementación de la simulación

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	//1. 目标空间中的\0
	while (*dest)
	{
		dest++;
	}
	//2. 追加内容到目标空间
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[30] = "hello";
	char arr2[] = "world";// {'w', 'o', 'r', 'l', 'd', '\0'};
	printf("%s\n", my_strcat(arr1, arr2)); // helloworld
	return 0;
}

2.3, strcmp

  • Función: Comparación de cadenas

strcmp compara el tamaño ASCII del carácter en la posición correspondiente, no la longitud de la cadena.

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "bbq";
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);  // -1
	return 0;
}
  • Aviso:
  1. Si la primera cadena es mayor que la segunda cadena, devuelve un número mayor que 0
  2. Si la primera cadena es igual a la segunda cadena, devuelve 0
  3. Si la primera cadena es menor que la segunda cadena, devuelve un número menor que 0

2.3.1 Implementación de la simulación

#include<stdio.h>
#include<assert.h>
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;
	/*if (*str1 > *str2)
		return 1;
	else
		return -1;*/
}
int main()
{
	char arr1[] = "abc";
	char arr2[] = "abc";
	int ret = my_strcmp(arr1, arr2);
	/*printf("%d\n", ret);*/
	if (ret<0)
	{
		printf("arr1<arr2");
	}
	else if (ret >0)
	{
		printf("arr1>arr2");
	}
	else
	{
		printf("arr1==arr2");
	}
	return 0;
}

3. Funciones de cadena con longitud limitada

3.1, strncpy

  • Función: copia la función del número especificado de elementos
#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "xxxxxxxxxxxxxxxx";
	char arr2[] = "hello bit";
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);  //helloxxxxxxxxxxx
}
  1. Esta función no se ve afectada por '\0' y copia números de caracteres de la cadena de origen al espacio de destino.
  2. El espacio de destino debe ser lo suficientemente grande para albergar el contenido de la cadena de origen.
  3. Si la longitud de la cadena de origen es inferior a num, después de copiar la cadena de origen, agregue 0 al final de la cadena de destino hasta num.
  • como sigue:
int main()
{
	char arr1[] = "xxxxxxxxxxxxxxxx";
	char arr2[] = "he";
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);  //he\0\0\0 ---》he
}

3.1.1 Implementación de la simulación

#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* dest, const char* str, size_t n)
{
	assert(dest && str);
	char* ret = dest;
	while (n--)
	{
		*dest++ = *str++;
	}
	return ret;
}
int main()
{
	char arr1[] = "xxxxxxxxxx";
	char arr2[] = "abcde";
	printf("%s\n", my_strncpy(arr1, arr2, 4));  // abcdxxxxxx
	return 0;
}

3.2, strncat

  • Función: función de cadena que conecta el número especificado de elementos
  • strncat concatena la cadena de origen especificada a partir de la posición de la cadena de destino contando de izquierda a derecha hasta el primer '\0'
#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20] = "hello";
	char arr2[] = "world";
	printf("%s\n", strncat(arr1, arr2, 3)); //hellowor
	return 0;
}
  • Aviso:

 

 Después de agregar strncat, tomará la iniciativa de poner un '\0' después de agregar para asegurarse de que sea una cadena.

3.2.1 Implementación de la simulación

#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dest, const char* str, size_t n)
{
	assert(dest && str);
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	while (n--)
	{
		*dest++ = *str++;
	}
	*dest = '\0';
	return ret;
}
int main()
{
	char arr1[20] = "hello\0xxxxx";
	char arr2[] = "bitxxxxx";
	printf("%s\n", my_strncat(arr1, arr2, 3)); //hellobit
	return 0;
}

3.3, strncmp

  • Función: implementa la función de comparación de números de caracteres en la posición especificada
#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcqqqqq";
	printf("%d\n", strncmp(arr1, arr2, 4));//-1
	printf("%d\n", strncmp(arr1, arr2, 3));//0
	return 0;
}

3.3.1 Implementación de la simulación

#include<stdio.h>
#include<assert.h>
int my_strncmp(char* dest, const char* str, size_t n)
{
	int ret = 0;
	assert(dest && str);
	while (n && !(*dest - *str))
	{
		n--;
		dest++;
		str++;
	}
	if (n && *dest - *str > 0)
		return 1;
	else if (n && *dest - *str < 0)
		return -1;
	return ret;
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcqqqqq";
	printf("%d\n", my_strncmp(arr1, arr2, 3)); //0
	return 0;
}

4. Búsqueda de cadenas

4.1, strstr

Función: determina si una cadena es un subconjunto de otra cadena, si es así, vuelve desde el primer igual hasta el final

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	char* ret = strstr(arr1, arr2);
	if (NULL == ret)
		printf("没找到\n");
	else
		printf("%s\n", ret);  // bbcdef
	return 0;
}

4.1.1 Implementación de la simulación

#include<stdio.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;
}
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbcq";
	char* ret = my_strstr(arr1, arr2);
	if (NULL == ret)
		printf("没找到\n");  //没找到
	else
		printf("%s\n", ret);
	return 0;
}

4.2, strtok

  • Función: Cortar una cadena de cadenas según el delimitador
  • Aviso:
  • char * strtok ( char * str, const char * sep );
  1. El parámetro sep es una cadena que define el conjunto de caracteres que se usarán como separadores.
  2. El primer parámetro especifica una cadena que contiene cero o más tokens separados por uno o más delimitadores en la cadena de separación.
  3. La función strtok encuentra el siguiente token en str, lo termina con \0 y devuelve un puntero a este token. (Nota: la función strtok cambiará la cadena que se está manipulando, por lo que la cadena segmentada por la función strtok generalmente es el contenido de una copia temporal y se puede modificar).
  4. El primer parámetro de la función strtok no es NULL, la función encontrará el primer token en str y la función strtok guardará su posición en la cadena.
  5. El primer parámetro de la función strtok es NULL, y la función comenzará en la posición guardada en la misma cadena y buscará el siguiente token.
  6. Si no hay más tokens en la cadena, se devuelve un puntero NULL.
#include <stdio.h>
#include <string.h>
int main()
{
	const char* p = "@.#,";
	char arr[] = "[email protected]#sh,ge";
	char buf[50] = { 0 };// "[email protected]#sh,ge";
	strcpy(buf, arr);
	/*char* str = NULL;
	for (str = strtok(buf, p); str != NULL; str=strtok(NULL, p))
	{
		printf("%s\n", str);
	}*/
	char* str = strtok(buf, p);
	printf("%s\n", str);
	str = strtok(NULL, p);//en
	printf("%s\n", str);
	str = strtok(NULL, p);//yu
	printf("%s\n", str);
	str = strtok(NULL, p);//sh
	printf("%s\n", str);
	str = strtok(NULL, p);//ge
	printf("%s\n", str);
	//strtok - 开始返回NULL
	return 0;
}

5. Informe de mensajes de error

5.1, terror

  • Función: traducir códigos de error en mensajes de error
  • Lenguaje C ', especifica alguna información, código de error - mensaje de error
#include<stdio.h>
#include<string.h>
int main() 
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d = %s\n", i, strerror(i));
	}
	return 0;
}

  •  Ejemplo de uso:
  • El lenguaje C puede manipular archivos y abrir archivos - fopen
  • Cuando se utiliza la función de biblioteca, si se produce un error, la variable de error global errno se establecerá como el código de error generado por la ejecución de la función de biblioteca.errno es una variable global proporcionada por el lenguaje C, que se puede utilizar directamente y colocado en el archivo errno.h.
#include<stdio.h>
#include <errno.h>
#include<string.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (NULL == pf)
	{
		//出错误的原因是什么
		printf("%s\n", strerror(errno));  //No such file or directory
		return 0;
	}
	//读文件
	//...
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

6. Operación de caracteres

6.1, función de clasificación de caracteres

función Devuelve verdadero si su argumento cumple las siguientes condiciones
escntrl cualquier personaje de control
es espacio Caracteres de espacio en blanco: espacio ' ', salto de página '\f', salto de línea '\n', retorno de carro '\r', tabulador '\t' o tabulador vertical '\v'
esdigito Dígitos decimales 0~9
esxdigito Dígitos hexadecimales, incluidos todos los dígitos decimales, letras minúsculas a~f, letras mayúsculas A~F
es bajo letras minúsculas a~z
essuperior Letras mayúsculas A~Z
isalfa Letras a~z o A~Z
isalnum Letras o números, a~z, A~Z, 0~9
es puntito Signos de puntuación, cualquier carácter gráfico que no sea un número o una letra (imprimible)
isgrafo cualquier carácter gráfico
imprimir Cualquier carácter imprimible, incluidos los caracteres gráficos y los espacios en blanco
  • Por ejemplo: isdigit
	char ch = '0';
	if (ch >= '0' && ch <= '9')
	{
        //复杂
	}
	if (isdigit(ch))
	{
        //方便快捷
	}

6.2, conversión de caracteres

int tolower ( int c ); //把大写转为小写
int toupper ( int c ); //把小写转为大写
#include<stdio.h>
#include <ctype.h>
int main()
{
	char ch = 0;
	while (ch = getchar())
	{
		if (islower(ch))
		{
			ch = toupper(ch);
		}
		else
		{
			ch = tolower(ch);
		}
		printf("%c", ch);
	}
	return 0;
}

7. Función de operación de memoria

7.1, memcpy

  •   Función: puede copiar diferentes tipos de datos
#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[5] = { 0 };
	memcpy(arr2, arr1, 5 * sizeof(arr1[0]));
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr2[i]);  // 1 2 3 4 5
	}
	return 0;
}
  • Aviso:
void * memcpy ( void * destination, const void * source, size_t num );
  1. La función memcpy copia números bytes de datos hacia atrás desde la ubicación de origen a la ubicación de memoria de destino.
  2. Esta función no se detiene cuando encuentra '\0'.
  3. Si hay alguna superposición entre el origen y el destino, el resultado de la copia es indefinido.

7.1.1 Implementación de la simulación

#include<stdio.h>
#include <assert.h>
void* my_memcpy(void* dest, const void*src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	while (num--) 
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr3[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr4[5] = { 0 };
	my_memcpy(arr4, arr3+5, 5*sizeof(arr3[0]));
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr4[i]);  //6 7 8 9 10
	}
	return 0;
}
  • De hecho, el lenguaje C solo requiere:
  1. memcpy puede copiar espacios de memoria que no se superponen
  2. memmove para manejar esas copias superpuestas

7.2, movimiento de memoria

Función: También se pueden copiar diferentes tipos de datos, pero pueden superponerse

#include<stdio.h>
#include<string.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr + 2, arr, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{ 
		printf("%d ", arr[i]); //1 2 1 2 3 4 5 8 9 10
	}
	return 0;
}
  • Aviso:
  1. La diferencia con memcpy es que el bloque de memoria de origen y el bloque de memoria de destino procesados ​​por la función memmove pueden superponerse.
  2. Si el espacio de origen y el espacio de destino se superponen, debe usar la función memmove para solucionarlo.

7.2.1 Implementación de la simulación

#include<stdio.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	
	if (dest < src)
	{
		//前->后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (num--)
		{
			*((char*)dest+num) = *((char*)src + num);
		}
	}
	return ret;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr + 2, arr, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{ 
		printf("%d ", arr[i]); //1 2 1 2 3 4 5 8 9 10
	}
	return 0;
}

7.3, conjunto de memoria

  • Función: Establece un espacio de memoria al valor que desees y modifícalo en bytes
#include<stdio.h>
#include<string.h>
int main()
{
	//char arr[20] = { 0 };
	//memset(arr, 'x', 10);
	//printf("%s\n", arr);  //xxxxxxxxxx
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memset(arr, '\0', 10);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);  // 0 0 0 4 5 6 7 8 9 10
	}
	//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ...将前10个字节改为0
	//00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
	return 0;
}

7.4, memcmp

  • Función: comparación de memoria
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

Compare números de bytes a partir de los punteros ptr1 y ptr2, no importa si hay '\ 0' o no, deje que compare algunos bytes y compare algunos bytes.

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = { 1,2,7,4,5 };
	int arr2[] = { 1,2,3,4,5 };
	printf("%d\n", memcmp(arr1, arr2, 9)); //1  // 9表示比较前9个字节
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/bit_zyx/article/details/122638256
Recomendado
Clasificación