String function and memory function

Posted by gelwa on Mon, 24 Jan 2022 12:12:13 +0100

This chapter focuses on the use and precautions of library functions dealing with characters and strings


The processing of characters and strings in C language is very frequent,

However, C language itself has no string type. Strings are usually placed in constant strings or character arrays.

String constants apply to string functions that do not modify them
 

catalogue

I strlen function: get string length

II String function with unlimited length

strcpy function: copy of string

strcat function: string concatenation

strcmp function: string comparison

III Introduction to string functions with limited length

strncpy function

strncat function

strncmp function

IV String lookup function

strstr function

strtok function

V Error message report

strerror function

Vi Character operation

1. Character classification function

2. Character conversion function

VII Memory operation function

memcpy function

memmove function

memset function

memcmp function

 

I strlen function: get string length

size_t strlen ( const char * str );

The string ends with '\ 0', and the strlen function returns the number of characters that appear before '\ 0' in the string

Note:

  • The string pointed to by the parameter must end with '\ 0'.
  • Note that the return value of the function is size_t. Is unsigned (error prone)

Examples

#include <stdio.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if(strlen(str2)-strlen(str1)>0)
{
printf("str2>str1\n");
}
else
{
printf("srt1<str2\n");
}
return 0;
}

Since the return value of the strlen function is size_t is an unsigned integer

When two unsigned integers are subtracted, the result is also an unsigned integer

So the result printed here is STR2 > STR1

Three ways to simulate the implementation of strlen function

Mode 1:

//Counter mode
int my_strlen(const char * str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}

Mode 2:

//Do not create temporary variable counters, use recursion
int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}

Mode 3:

//Pointer - pointer mode
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}

II String function with unlimited length

strcpy function: copy of string

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

 Copies the C string pointed by source into the array pointed by destination, including theterminating null character (and stopping at that point).

  • The source string must end with '\ 0'.
  • The '\ 0' in the source string will be copied to the destination space.
  • The destination space must be large enough to hold the source string.
  • Target space must be variable

Simulation Implementation

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);//Assert
	char* ret = dest;
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
 
int main()
{
	char arr1[20] = "xxxxxxxxxxxxx";
	char arr2[] = "hello";
    my_strcpy(arr1, arr2);
	printf("%s", arr1);
	printf("%s\n",my_strcpy(arr1, arr2));
	return 0;
}

strcat function: string concatenation

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

Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.

  • The source string must end with '\ 0'.
  • The target space must be large enough to accommodate the contents of the source string.
  • The target space must be modifiable.
     

Simulation Implementation

char* my_strcat(char* dest, const char* src)
{
	assert(dest&&src);
	int i = 0;
	while (*(dest + i) != '\0')
	{
		i++;
	}
	while (*src != '\0')
	{
		*(dest + i++) = *src++;
	}
	*(dest + i) = '\0';
	return dest;
}

strcmp function: string comparison

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

This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.
Standard provisions:

  • If the first string is greater than the second string, a number greater than 0 is returned
  • If the first string is equal to the second string, 0 is returned
  • If the first string is less than the second string, a number less than 0 is returned
int my_strcmp (const char * src, const char * dst)
{
int ret = 0 ;
assert(src != NULL);
assert(dest != NULL);
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}

III Introduction to string functions with limited length
 

strncpy function
 

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

 Copies the first num characters of source to destination. If the end of the source C string(which is signaled by a null-character) is found before num characters have been copied,destination is padded with zeros until a total of num characters have been written to it.

  • Copy num characters from the source string to the destination space.
  • If the length of the source string is less than num, after copying the source string, append 0 to the end of the target until num

 

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "xxxxxxxxxxxxxxxx";
	char arr2[] = "hello world";
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);  //helloxxxxxxxxxxx
}

If the length of the source string is less than num, after copying the source string, append 0 to the end of the target until num

int main()
{
	char arr1[] = "xxxxxxxxxxxxxxxx";
	char arr2[] = "he";
	strncpy(arr1, arr2, 5);
	printf("%s\n", arr1);  //he\0\0\0 ->he
}

Simulation Implementation

#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;
}

 

strncat function
 

  • Function: a string function that connects the specified number of elements
  • strncat connects the source specified string from the destination string counting from left to right to the first '\ 0'
char * strncat ( char * destination, const char * source, size_t num );

Appends the first num characters of source to destination, plus a terminating null-character.

If the length of the C string in source is less than num, only the content up to the terminating null-character is copied
 

#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20];
	char str2[20];
	strcpy(str1, "To be ");
	strcpy(str2, "or not to be");
	strncat(str1, str2, 6);
	puts(str1);
	return 0;
}

  • be careful:

After strncat is appended, it will actively put a '\ 0' after the append to ensure that it is a string.

Simulation Implementation

#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[] = "worldxxxxx";
	printf("%s\n", my_strncat(arr1, arr2, 5)); //helloworld
	return 0;
}

strncmp function

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

The comparison shows that two characters are different, or a string ends, or num characters are all compared

  • Function: implement the character number comparison function at the specified position

 

#include <stdio.h>
#include <string.h>
int main()
{
	char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
	int n;
	puts("Looking for R2 astromech droids...");
	for (n = 0; n < 3; n++)
		if (strncmp(str[n], "R2xx", 2) == 0)
		{
			printf("found %s\n", str[n]);
		}
	return 0;
}

 

Simulation Implementation

#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)); 
	return 0;
}

IV String lookup function

strstr function

Function: judge whether a string is a subset of another string. If yes, return the address from the first equal

 Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of
str1.

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

Simulation Implementation

#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[] = "bbc";
	char* ret = my_strstr(arr1, arr2);
	if (NULL == ret)
		printf("Can't find\n"); 
	else
		printf("%s\n", ret);//bbcdef
	return 0;
}

 

strtok function

  • Function: cut a string of strings according to the separator

Note:

char * strtok ( char * str, const char * sep );
  • The sep parameter is a string that defines the set of characters used as delimiters.
  • The first parameter specifies a string that contains 0 or more tags separated by one or more separators in the sep string.
  • The strtok function finds the next tag in str, ends it with \ 0, and returns a pointer to this tag. (Note: the strtok function will change the string to be manipulated, so the string segmented by the strtok function is generally a temporary copy of the content and can be modified.)
  • The first parameter of the strtok function is not NULL. The function will find the first tag in str, and the strtok function will save its position in the string.
  • The first parameter of strtok function is NULL. The function will start at the position saved in the same string to find the next tag.
  • If there are no more tags in the string, a NULL pointer is returned
     
#include <string.h>
int main()
{
	const char* p = "@.#,";
	char arr[] = "zhangsan@qq.com";
	char buf[50] = { 0 };// "zhangsan@qq.com";
	strcpy(buf, arr);
	char* str = strtok(buf, p);
	printf("%s\n", str);//zhangsan
	str = strtok(NULL, p);
	printf("%s\n", str);//qq
	str = strtok(NULL, p);
	printf("%s\n", str);//com
	str = strtok(NULL, p);
	printf("%s\n", str);
	//strtok - return NULL from start
	return 0;
}

 

V Error message report

strerror function

  • Function: translate the error code into error information
  • In C language, some information is specified, error code - error information
#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;
}

 

 

 

Examples of uses:

C language can operate files, open files - fopen

When the library function is used, if an error occurs, the global error variable errno will be set as the error code generated by this execution of the library function. Errno is a global variable provided by C language and can be used directly. It is in errno H in the file

 

#include<stdio.h>
#include <errno.h>
#include<string.h>
int main()
{

	FILE* pf = fopen("test.txt", "r");
	if (NULL == pf)
	{
		//What is the reason for the error
		printf("%s\n", strerror(errno));  //No such file or directory
		return 0;
	}
	//read file
	//...
	//Close file
	fclose(pf);
	pf = NULL;
	return 0;
}

Vi Character operation

1. Character classification function

 

For example: isdigit

	char ch = '0';
	if (ch >= '0' && ch <= '9')
	{
        //complex
	}
	if (isdigit(ch))
	{
        //Convenient and fast
	}

 

2. Character conversion function

int tolower ( int c ); //Change uppercase to lowercase
int toupper ( int c ); //Convert lowercase to uppercase
#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;
}

VII Memory operation function


memcpy function

void * memcpy ( void * destination, const void * source, size_t num );

 

Function: it can copy different types of data

#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;
}

be careful:

  1. The function memcpy copies num bytes of data back to the memory location of destination from the location of source.
  2. This function will not stop when it encounters' \ 0 '.
  3. If there is any overlap between source and destination, the copied result is undefined.

Simulation Implementation

#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;
}
  • C language only requires:
  1. memcpy can copy non overlapping memory space
  2. memmove to handle those overlapping copies

memmove function

Function: it can copy different types of data, but it can overlap

 

#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;
}

Attention

  1. The difference from memcpy is that the source memory block and target memory block processed by the memmove function can overlap.
  2. If the source space and target space overlap, you have to use the memmove function.

Simulation Implementation

#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)
	{
		//Front - > rear
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//Rear - > front
		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;
}



memset function

Function: set a piece of memory space to the value you want, and modify it in 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 ... Change the first 10 bytes to 0
	//00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
	return 0;
}

 

memcmp function

Function: memory comparison

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

Compare num bytes starting from ptr1 and ptr2 pointers, regardless of whether there is' \ 0 ', you can compare a few bytes if you let it compare a few 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 means comparing the first 9 bytes
	return 0;
}

 

Topics: C Back-end