An article lets you understand character functions + string functions

insert image description here

  1. List item

foreword

The processing of characters and strings in C language is very frequent, but C language itself does not have a string type. Strings are usually placed in constant strings or in character arrays. String
constants are suitable for those who do not modify it. String functions

1. Find the length of the string

1.1 shot

Its return value is an unsigned integer string of size_t with
'\0' as the end mark, and the strlen function returns the number of characters that appear before '\0' in the string (excluding '\0')
The string pointed to by the parameter must end with '\0'
Note that the return value of the function is size_t, which is unsigned (error-prone)
Learn the simulation implementation of the strlen function
The strlen function introduces
the basic form of strlen

size_t strlen ( const char * str );

Here is a line of code

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

int main()
{
    
    
	if (strlen("abc") - strlen("abcdef") > 0)
	{
    
    
		printf("大于\n");
	}
	else
	{
    
    
		printf("小于等于\n");
	}

	return 0;
}

I believe that many people think that the result of this line of code output must be greater than or
equal to the opposite of the initial output is greater than
insert image description here

So why?
The value of the first strlen is 3, and the value of the second strlen is 6. It seems that the value of 3-6 is -3, but the return value of strlen is unsigned. The result returned by the subtraction of
two unsigned numbers will also be returned. Treated as an unsigned number
-3 is treated as an unsigned number?
The original code of -3 is 10000000000000000000000000000011
The inverse code of -3 is 11111111111111111111111111111100 The complement
of -3 is 111111111111111111111111111111101
Whether the sign bit of an unsigned number is 0 or 1, it represents an integer,
so the number represented by the complement of -3 is very large,
so we Writing code like this can’t achieve our goal,
so let’s imagine that converting the size_t unsigned number to an int integer can achieve the result we want
Now let’s simulate and implement strlen

#include<stdio.h>
#include <string.h>
size_t my_strlen(const char* str)
{
    
    
	int count = 0;
	while (*str != '\0')
	{
    
    
		count++;
		str++;
	}
	return count;
}
int main()
{
    
    
	size_t sz = my_strlen("abc");
	printf("%u\n", sz);
	return 0;
}

my_strlen asks for a length "abc", and I take a sz to receive it. We can simulate the return type of the library function strlen to design the return type of sz as size_t. At this time, when we call the function, the function parameters of my_strlen should also be designed to be the same as the library function strlen is as convenient for us to understand. When we encounter \0, we stop and return the value of count, so why did the person who designed the library function strlen design the return type of strlen as an unsigned number size_t?
In order to solve this doubt, let's first think about whether it is possible for a string to return a negative number? It is obviously impossible, so if I call the return type of the library function strlen int, int can represent both integers and negative numbers, which feels unreasonable, so we directly write it as size_t, and unsigned numbers represent integers. Of course, size_t is
also Can be written as unsigned int: unsigned integer

2 String functions with unlimited length

2.1strcpy

Copies the C string pointed by source into the array pointed by destination, including the
terminating null character (and stopping at that point ) Space The target space must be large enough to ensure that the source string can be stored The target space must be variable Learn to simulate implementation




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

	//char arr2[] = "hello bit";
	char* arr1 = "xxxxxxxxxx";
	char arr2[6] = {
    
     'a', 'b', 'c', 'd', 'e' , '\0'};
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

The \0 here is the correct code. If there is no \0, the program will report an error. I don’t know when to stop,
so it is absolutely impossible without \0

#include<stdio.h>
#include <string.h>
int main()
{
    
    
	//char arr1[3] = "";
	//char arr2[] = "hello bit";
	char* arr1 = "xxxxxxxxxx";
	char arr2[6] = {
    
     'a', 'b', 'c', 'd', 'e' , '\0'};
	strcpy(arr1, arr2);
	printf("%s\n", arr1);

	return 0;
}

The space opened up by arr1 is only three bytes, and the strings in arr2 cannot fit completely,
so the target space should be large enough. The character
pointer char*arr1 is a constant string and cannot be modified. The correct way to write it is in char Add const in front of the star , then we simulate the code form of the strcpy
function strcpy by imitating the library function strcpy

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

Let's look at the code directly

#include<stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
    
    
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*src != '\0')
	{
    
    
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
	return ret;
}
int main()
{
    
    
	char arr1[20] = "hello world";
	char arr2[] = "xxxxx";
	my_strcpy(arr1 + 6, arr2);
	printf("%s\n", arr1);
	return 0;
}

The return type of the custom function my_strcpy refers to the return type of the library function strcpy char*//The \0 in
the last src will also be assigned to the star dest(destnation) The return type of the target function dest of the custom function my_strcpy returns a char star The address of the first element The best way to write here is to add a const in front of char* src, because it is a constant string. We have learned the assert function before—assertion. Here we dereference the pointer variable, and we must ensure the pointer Validity, what if there is a problem with the pointer? What about NULL—a null pointer? So here we make an assertion to judge that the pointer is not NULL. Reminder to use the assert assertion must include the header file #include<assert.h> This code is a bit redundant. We try to modify the while loop slightly







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

The semicolon in the while statement does not execute any statement, does it look comfortable
This line of code can still achieve our expected effect
Here is an example
to see the code

#include<stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
    
    
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest++ = *src++)
	{
    
    
		;
	}

	return ret;
}
int main()
{
    
    
	char arr1[20] = "hello world";
	char arr2[] = "xxxxx";
	my_strcpy(arr1 + 6, arr2);
	printf("%s\n", arr1);
	return 0;
}

If I only want to change the string of world, I only need to add 6 to the address of the first element of the arr array and then call the function to traverse in turn.

2.2strcat

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 be terminated with '\0'.
The destination space must be large enough to hold the contents of the source string.
The target space must be modifiable.
How about adding strings to yourself?
strcat function
library function strcat code form

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

Look directly at the code first

#include<stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
    
    
	char arr1[20] = "hello ";
	char arr2[] = "world";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

This function needs to pay attention to a few points
1: the target space string must have \0 so that I can find where to append
2: the source string also needs to have \0 to stop after appending
3: the target space must be large enough to put the append The finished string
Let's simulate the implementation of the following library function strcat
First look directly at the code

#include<stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
    
    
	assert(dest && src);
	char* ret = dest;
	//1. 找目标空间中的\0
	while (*dest)
	{
    
    
		dest++;
	}
	while (*dest++ = *src++)
	{
    
    
		;
	}
	return ret;
}
int main()
{
    
    
	char arr1[20] = "hello ";
	char arr2[] = "world";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

The asterisk dest stops when it encounters \0, ending the first while loop. The
second while loop is to append the source string to the target string.
There is still an assertion here, so I won’t explain too much here.
The return value is still Return the address of the first element of the target string, and print the string in order through the address of the first element

2.3strcmp

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.
The standard stipulates that
the first character string is greater than the second A string, then return a number greater than 0
The first string is equal to the second string, then return 0
The first string is less than the second string, then return a number less than 0
So how to judge the two strings ?
Introduction to strcmp function
Library function strcmp code form

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

Let's directly simulate and implement the library function strcmp

#include<stdio.h>
#include <string.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);
}
//在VS
//> 1
//= 0
//< -1
//

int main()
{
    
    
	int ret = my_strcmp("bbq", "bcq");
	if (ret>0)
		printf(">\n");

	printf("%d\n", ret);
	return 0;
}

In the VS compiler environment, if it is greater than 0, it will return 1,
if it is less than 0, it will return -1
is equal to 0, and it will return 0.
I can directly write it as

return (*str1 - *str2);

The C language stipulates that it is enough to return a positive or negative number. It is not necessary to return 1, -1, 0,
but in the VS environment, it returns -1, 0,
1. The return type of the library function strcmp is int, so we define an integer ret
The return type of the call function is int
and enters the while loop. If our asterisk str1 is \0, it means that our two strings are equal, and then return \0.
The second if is to judge the size, and it is easy to understand. There is not much here explain

3 Introduction to length-restricted string functions

3.1strncpy

Library function strncpy introduces
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 target space.
If the length of the source string is less than num, after copying the source string, add 0 to the end of the target until num.

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

int main()
{
    
    
	char arr1[20] = "abcdef";
	char arr2[] = "xxx";
	strncpy(arr1, arr2, 5);

	return 0;
}

Library function strncpy code form

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

3.2strncat

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.
库函数strncat介绍
代码形式

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

Implementation code

//int main()
//{
    
    
//	char arr1[20] = "abcdef\0yyyyyyyy";
//	char arr2[] = "xxxxxxxxx";
//	strncat(arr1, arr2, 3);
//
//	return 0;
//}
/* strncat example */
#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;
}

3.3strncmp

Compare until another character is different or a string ends or all num characters are compared
insert image description here
Code form

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

Implementation code

//int main()
//{
    
    
//	char arr1[] = "abcqwertyuiop";
//	char arr2[] = "abcdef";
//	printf("%d\n", strncmp(arr1, arr2, 4));
//
//	return 0;
//}
//
/* strncmp example */
#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;
}

4. String lookup

4.1strstr

Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
库函数strstr介绍

/* strstr example */
#include <stdio.h>
#include <string.h>
int main ()
{
    
    
  char str[] ="This is a simple string";
  char * pch;
  pch = strstr (str,"simple");
  strncpy (pch,"sample",6);
  puts (str);
  return 0;
}

code form

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

Let's look directly at the code first

#include<stdio.h>
#include <string.h>
#include <assert.h>
char* my_strstr(char *str1, char* str2)
{
    
    
	char* cp = str1;
	char* s1 = cp;
	char* s2 = str2;

	if (*str2 == '\0')
		return str1;

	while (*cp)
	{
    
    
		//开始匹配
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
    
    
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cp;

		cp++;
	}

	return NULL;
}


int main()
{
    
    
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";

	char* ret = my_strstr(arr1, arr2);
	if (ret != NULL)
		printf("%s\n", ret);
	else
		printf("找不到\n");

	return 0;
}

The return type of the function call is char to return the address of the first element of the string.
The star s1 is a and not \0, and the star s2 is b and not \0. They are not equal. If they are not equal, the loop will exit, and then cp++ will get b and go back and forth in turn. When
finding After the string in the character array is finished, stop and return
the address of the first element of the char type, and then make a judgment that the asterisk s2 is equal to \0, return the pointer of the char* type, and then print the string from the first address

4.2 strtok

The sep parameter is a string that defines the set of characters used as separators. The
first parameter specifies a string that contains 0 or more tokens separated by one or more separators in the sep string. The strtok
function finds str and end it with \0, and return a pointer to this mark (note: the strtok function will change the string being manipulated, so the strings split using the strtok function are generally copied temporarily content and can be modified)
the first parameter of the strtok function is not NULL, the function will find the first token in str, the strtok function will save its position in the string, the first parameter
of the strtok function is NULL, the function will be in Start from the saved position in the same string, search for the next token
If there are no more tokens in the string, return NULL Introduction to pointer
library function strtok
Code form

char * strtok ( char * str, const char * sep

The basic implementation form of the library function strtok

/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
    
    
  char str[] ="- This, a sample string.";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
 {
    
    
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
 }
  return 0;
}

Simulate the implementation of library function strtok

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
    
    
	char arr[] = "[email protected]@666#777";
	char copy[30];
	strcpy(copy, arr);

	char sep[] = "@.#";
	char* ret = NULL;

	for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL, sep))
	{
    
    
		printf("%s\n", ret);
	}
	return 0;
}

The first parameter of the first library function strtok should be passed to copy.
The first parameter of the second library function strtok should be NULL.
The third library function strtok is the same - NULL
is also used for the condition part of the for loop. It is the last semicolon part. If the split string is not a null pointer, it will continue to print in a loop. If it is false, it will jump out of the loop.

5 Error message reporting

5.1str error

Return error code, the corresponding error message
code format

char * strerror ( int errnum );

Introduction to library function strerror

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
    
    
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d: %s\n", i, strerror(i));//
	}
	return 0;
}

insert image description here
We know that there is a knowledge of file operation in C language.
The first step is to open the file.
The second step is to read or write the file.
The third step is to close the file.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
    
    
	//C语言中可以操作文件
	//操作文件的步骤
	//1. 打开文件
	//2. 读/写
	//3. 关闭文件
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
    
    
		printf("fopen: %s\n", strerror(errno));
		perror("fopen");
		//fopen: xxxxxx
		return 1;
	}
	//读文件
	//...
	//关闭文件
	fclose(pf)
	return 0;
}

insert image description here
We can create a .txt file directly on our current VS path, but if you turn off the file attribute display and add a .txt suffix, the printed result is still wrong. When you open the file attribute, you will find The file itself comes with a .txt.
The specific operation is as follows. Open it to view and click to display. Click the file extension to have a suffix. You must pay attention to the details
insert image description here

6 character operation

6.1 Character classification function

insert image description here
The specific operation is as follows

//代码1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
int main()
{
    
    
	printf("%d\n", isupper('a'));
	printf("%d\n", isdigit('2'));
	printf("%c\n", tolower('A'));
	printf("%c\n", tolower('s'));

	char arr[20] = {
    
     0 };
	gets(arr);//遇到空格继续读
	
	char* p = arr;
	while (*p)
	{
    
    
		if (isupper(*p))// *p>='A' && *p<='Z'
		{
    
    
			*p = tolower(*p);//*p = *p+32;
		}
		p++;
	}
	printf("%s\n", arr);
	return 0;
}
//代码2
/* isupper example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
    
    
  int i=0;
  char str[]="Test String.\n";
  char c;
  while (str[i])
 {
    
    
    c=str[i];
    if (isupper(c)) 
        c=tolower(c);
    putchar (c);
    i++;
 }
  return 0;

Guess you like

Origin blog.csdn.net/fjj2397194209/article/details/131662651