当前位置:网站首页>C language interview tube: talk about the functions of various string functions. I: I don't know. Interviewer: come back for an interview when the young man has learned how to do it.

C language interview tube: talk about the functions of various string functions. I: I don't know. Interviewer: come back for an interview when the young man has learned how to do it.

2022-06-09 03:43:00 Chenze

write in front

Hello everyone , I'm Chen Ze , I hope after you read it , It can help you , Insufficient, please correct ! Learn and communicate together
2021 Blog star of the year, Internet of things and embedded development TOP5~2021 Blog star Top100~ Alibaba cloud experts ^ Star Blogger ~ Nuggets ⇿InfoQ Creator ~ Zhou Bang 54» General list 2999
This paper is written by Chen Ze original CSDN First episode If you need to reprint, please inform
Personal home page -
Chen Ze's blog _CSDN Blog
Welcome to → give the thumbs-up + Collection ️ + Leaving a message. ​
Series column -
【C】 series _ Chen Ze's blog -CSDN Blog
this paper de Creation time   ⇨  2021   year   2   month   11   Japan
️ We are not on the stage of our choice , Acting is not the script we chose

『C Language 』 character string de function  

write in front

Preface  

strlen() - Calculate string length

strlen() Function code example

Create a custom function implementation strlen() The function of

strcpy() - Copy string

strcpy() Function code example

Create a custom function implementation strcpy() The function of

strcat() - Connection string

strcat() Function code example  

Create a custom function implementation strcat() The function of

strcmp() - Compare strings

strcmp() Function code example  

Create a custom function implementation strcmp()   

Limit  

strncpy() - Copy string ( Limited by length )

strncpy() Function code example

strncpy() Source code implementation  

strncat() - Connection string ( Limited by length )

strncat() Function code example

strncat() Source code implementation  

strncmp() - Compare strings ( Limited by length ) 

strncmp() Function code example   

strncat() Source code implementation

strstr() - Find another string in one string

strstr() Function code example

Create a custom function implementation strstr()

strtok() - Cut string

strtok() Function code example

strtok() Source code implementation

strerror() - Return error code  

strerror() Function code example

strerror() Source code implementation

Last

Preface  

In this blog, let's introduce the use of string functions , Most people have just started to learn about the use of string functions. They have only known the use of several string functions for some time image strlen()、strcpy()、strcat()、strcmp()、 The use of these four string library functions . The string function is definitely not only the four library functions , In fact, string functions can be said to be " multifarious " 了 , In this blog, I will introduce various uses of string functions in detail .

In the use of C Remember to add the corresponding header file when you use the string library function of #include<string.h>               

Remember Sanlian (o゚v゚)ノ

strlen() - Calculate string length

strlen() The function is declared as follows

size_t strlen ( const char * str );

Get string length .

return C character string str The length of .

 str  To calculate the length of a string .

A string of '\0' As an end sign ,strlen The return value of the function is the number of characters in the string ( It doesn't contain '\0')

Be careful : The return value of the function is unsigned unsigned It's easy to make mistakes の.

Size_t→ It's an unsigned thing (unisgned int) Integer type . 

→strlen How it works : Just give me an address , that strlen You can use the backward number symbol , To meet '\0' Will stop .

strlen() Function code example

Use strlen() The function code example is as follows

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>

int main(void)
{
	char str[20] = {"44778899"};

	int len = strlen(str);
	printf("%s  Is the length of the  %d\n", str, len);

	return(0);
}

The operation results are as follows →44778899 Is the length of the 8 

Of course, we should also pay attention to :char str[] = {'a','b','c'}; If so, there is no '\0', Then the result is a random value ! Still follow the above code to demonstrate .

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>

int main(void)
{
	char str[] = {'a','b','c'};

	int len = strlen(str);
	printf("%s  Is the length of the  %d\n", str, len);

	return(0);
}

The result of such a run would be a random value , Because we don't know the backslash '\0' Where is the . 

Create a custom function implementation strlen() The function of

The sample code is as follows : 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>//assert The header file 
int My_strlen(const char *arr)
{
	unsigned int Count = 0;// Statistical characters cannot be negative !
    assert(arr!=NULL);// By adding assertions here, we can ensure that when we enter a string, it will not be a null pointer 
	while (*arr != '\0')
	{
		Count++;
		*arr++;
	}
	return Count;// Returns the length of the computer 
}
int main(void)
{
	char enter[20] = { 0 };
	printf(" Please enter the string ->:");
	scanf("%s", &enter);
	int ret = My_strlen(enter);
	printf("The total number of input strings:%d\n",ret);
	return 0;
}

The operation results are as follows

Please enter the string :C Language is the best in the world  

The total number of input strings:7


strcpy() - Copy string

strcpy() The function is declared as follows  

char *strcpy(char *dest, const char *src)

hold  src  The string you point to is copied to  dest.

Note that if the target array dest Not big enough , And the length of the source string is too long , It may cause buffer overflow . therefore ,dest Be big enough , So that we can be src Put it away .

dest Point to the target array used to store the copied content .

src The string to copy .

This function returns a string pointing to the final destination dest The pointer to .

strcpy() In the original character to ensure that you have src The space size of existing characters is also called subscript .

Be careful : The pointer type of the return value here can be void * It can also be char * The type of .

strcpy() Function code example

Use strcpy() The function code example is as follows

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

int main ()
{
  char str1[]="C Language ";
  char str2[40];
  char str3[40];
  strcpy (str2,str1);
  strcpy (str3,"C++ Language ");
  printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
  return 0;
}

The operation results are as follows

str1: C Language
str2: C Language
str3: C++ Language
 

Of course, we should also pay attention to :char str[ ] = {'a','b','c'}; If you want to store like this, the reason is very simple '\0', The sample code is as follows :

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>

int main()
{
	char str1[] = { 'a', 'b', 'c' };
	char str2[40];
	strcpy(str2, str1);
	printf("%s", str2);
	return 0;
}

The operation results are as follows

  

It will be like this with random values , Because we don't know '\0' Where is it .

Of course, if so char str1[] = { 'a', 'b', 'c','\0'}; It won't be because we added... To the last element '\0'. 

Create a custom function implementation strcpy() The function of

The sample code is as follows : 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <assert.h>
void My_strcpy(char *dest, const char *src)
{
	assert(dest != NULL);
	assert(src != NULL);
	while (*src != '\0')
	{
		*dest = *src;// Assign a value 
		*src++;
		*dest++;// Point to the next character 
	}
}
int main(void)
{
	char *p = "C Language ";
	char str[20] = { 0 };
	My_strcpy(str, p);
	printf("str = %s\n",str);
	return 0;
}

The operation results are as follows

str = C Language


strcat() - Connection string

strcat() The function is declared as follows  

char *strcat(char *dest, const char *src)

Append a copy of the source string to the destination string .

dest → Point to target array , The array contains a C character string , And enough to hold the appended string .

src →  Point to the string to append , The string does not override the target string .

This function returns a string pointing to the final destination dest The pointer to .

hold  src  The string pointed to is appended to  dest  The end of the string that you are pointing to .

You can't add programs to yourself , like this :

char arr[20] = "Cyuyan"
strcat(arr,arr);
printf("%s\n",arr);

It won't work like this , Originally, my array stored :Cyuyan\0, Because this space is long enough, there is still content behind it . So if we want to add, it will be like this :CyuyanCyuyan, In essence, our slash 0 Will be in CyuyanCyuyan This string n Behind . But slashes 0 It is covered. , So who covered it , Is added by oneself arr Covered by . This will form a cycle , Because we'll never find the backslash 0-O-

strcat() Function code example  

Use strcat() The function code example is as follows

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
	char arr1[20] = "hello C";
	char arr2[20] = "yuyan";
	strcat(arr1, arr2);
	printf("arr1 = %s\n", arr1);
	return 0;
}

The operation results are as follows  

arr1 = hello Cyuyan

Let's take a look at the steps of its debugging results 🧐

Create a custom function implementation strcat() The function of

The idea is very simple. In fact

Ⅰ→dest Find the target string '\0'

Ⅱ→ Then append the source data to the string '\0' Behind , Be careful : Is included '\0' Of

The sample code is as follows : 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char *My_strcat(char *dest, const char *src)
{
	assert(dest && src != NULL);// Assertion 
	char *ret = dest;
	while (*dest != '\0')//'\0' Of ASCLL The code value is 0
	{
		dest++;
	}
    //dest Pointing to '\0'
	while (*dest++ = *src++)
	{
		;
	}
    /* amount to 
	while (*src != '\0')
	{
		*dest++ = *src++;
	}*/
	return ret;
}
int main(void)
{
	char arr1[20] = "hello C";
 	char arr2[20] = "yuyan";
	printf("%s\n", My_strcat(arr1, arr2));
	return 0;
}

The operation results are as follows  

hello Cyuyan

⒈ notes → There are many details in the above code, which is worth debugging. Here are the running steps . Such as

⒉ notes →'\0' In fact, it also corresponds to C Empty character of language NULL Decimal system 0 Value .


strcmp() - Compare strings

strcmp()  The function is declared as follows  

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

take C Language character string str1 And C Language character string str2 Compare .

This function starts comparing the first character of each string . If they are equal to each other , Then continue with the following pairs , Until the characters are different or reach the terminating null character . This function performs a binary comparison of characters .

str1 → The first string to compare .

str2 → The second string to compare .

Compare the size of each character ASCll The value of the code .

The return value of this function is as follows : This function has a return value int 

If the return value is less than 0, said str1 Less than str2.

If the return value is greater than 0, said str1 Greater than str2.

If the return value is equal to 0, said str1 be equal to str2.

strcmp() Function code example  

Use strcmp() The function code example is as follows

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char str1[20] = { 0 };
	char str2[20] = { 0 };
	puts(" Please enter the first string :");
	scanf("%s", &str1);
	puts(" Please enter the second string :");
	scanf("%s", &str2);
	puts(" The value returned :");
	printf("%d",strcmp(str1, str2));
	return 0;
}

The results of the first run

Please enter the first string :abc
Please enter the second string :abc
The value returned :0

The result of the second run

Please enter the first string :abcd
Please enter the second string :abc
The value returned :1

The result of the third run  

Please enter the first string :abc
Please enter the second string :abcd
The value returned :-1

Create a custom function implementation strcmp()   

The idea is very simple. In fact

Equal to 0、 Greater than return 1、 Less than return -1, Important notes are actually written .

The sample code is as follows :  

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char *str1, const char *str2)
{
	assert(str1 && str2 != NULL);
	while (*str1 == *str2)
	{
		// Judge equality , Having an equality means *str2 It's the same 
		if (*str1 == '\0')
		{
			return 0;
		}
		*str1++;
		*str2++;// Self increasing comparison 
	}
	if (*str1 > *str2)
		return 1;// Greater than 
	else
		return -1;// Less than 
	// In fact, there is a simpler way , Greater than less than .
	//return *str1 - *str2;
	// This is the concept of pointer minus pointer , The previous introduction said !
}
int main()
{
	char str1[20] = { 0 };
	char str2[20] = { 0 };
	puts(" Please enter the first string :");
	scanf("%s", &str1);
	puts(" Please enter the second string :");
	scanf("%s", &str2);
	int ret = my_strcmp(str1, str2);
	printf(" The value returned :%d\n",ret);
	return 0;
}

The results of the first run

Please enter the first string :abc
Please enter the second string :abc
The value returned :0

The result of the second run

Please enter the first string :abcd
Please enter the second string :abc
The value returned :1

The result of the third run  

Please enter the first string :abc
Please enter the second string :abcd
The value returned :-1

The above four string functions are what we learned C Language must be mastered , Including the implementation of analog string functions is also necessary , This benefit can exercise our understanding of the function library , Enhance your ability to write code , It is recommended to watch it again and again , Remember to master these four string functions ~ 


Limit  

Above strcpy、strcat、strcmp、 Length is an unlimited string function

The following is a string function with limited length >>>

Start by remembering that the following one only needs to be added to the above one str Back +n that will do (^∀^●)ノシ

The following describes 3 These functions are relatively safer to use than on , But it's not absolutely safe .


strncpy() - Copy string ( Limited by length )

This function is actually the same as strcpy() The function is as like as two peas , The only difference is strncpy() One more parameter , That parameter is limited by length .

strncpy() The function is declared as follows  

char *strncpy(char *dest, const char *src, size_t n)

hold  src  The string you point to is copied to  dest, Copy at most  n  Characters .

When src The length of is less than n when ,dest The rest of the will be filled with empty bytes .

dest → Point to the target array used to store the copied content .

src → The string to copy .

n → The number of characters to copy from the source .

Size_t→ Is an unsigned integer type .

This function finally returns the copied string . 

strncpy() Function code example

Use strncpy() The function code example is as follows

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
	char str1[20] = "helloC";
	char str2[] = "HELLO";
	printf(" byte =%d\n", sizeof(str2));
	printf("str = %s\n",strncpy(str1, str2, sizeof(str2)));
	return 0;
}

The operation results are as follows  

byte = 6

str = HELLO 

sizeof(str2) It's equivalent to 6 Bytes , because char For a byte There are elements in it 6 One includes '\0'

It might be better to have a look at the debugging results

Let's look at the next example   

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
	char str1[20] = "helloC";
	char str2[] = "HELLO";
	printf(" byte =%d\n", sizeof(char));
	printf("str = %s\n", strncpy(str1, str2, sizeof(char)));
	return 0;
}

The operation results are as follows  

byte = 1

str = HELLO 

sizeof(char) The result is a byte , because char The type size is one byte !

It might be better to have a look at the debugging results

strncpy() Source code implementation  

The sample code is as follows :

char * __cdecl strncpy (
        char * dest,
        const char * source,
        size_t count
        )
{
        char *start = dest;

        while (count && (*dest++ = *source++))    /* copy string */
                count--;

        if (count)                              /* pad out with zeroes */
                while (--count)
                        *dest++ = '\0';

        return(start);
}

strncat() - Connection string ( Limited by length )

strncat() The function is declared as follows   

char *strncat(char *dest, const char *src, size_t n)

hold  src  The string pointed to is appended to  dest  The end of the string that you are pointing to , until n The length of .

dest→ Point to target array , The array contains a C Language character string , And enough to hold the appended string , Include additional null characters .

src→ The string to append .

n→ The maximum string appended .

Size_t→ It's an unsigned thing (unisgned int) Integer type . 

This function returns a string pointing to the final destination dest The pointer to .

Be careful : The pointer type of the return value here can be void It can also be char *🧨

strncat() Function code example

Use strncpy() The function code example is as follows

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
	char str1[20];
	char str2[20];
	strcpy(str1, "Cyuyan");
	strcpy(str2, "yyds");
	printf(strncat(str1, str2, 5));// Append string !
	return 0;
}

The operation results are as follows  

Cyuyanyyds 

It might be better to have a look at the debugging results

We put  Size_t The parameter is changed to ④ Let's see

printf(strncat(str1, str2, 4));

The running result is still the same as the above . 

strncat() Source code implementation  

The sample code is as follows :

char * __cdecl strncat (
        char * front,
        const char * back,
        size_t count
        )
{
        char *start = front;

        while (*front++)
                ;
        front--;

        while (count--)
                if (!(*front++ = *back++))
                        return(start);

        *front = '\0';
        return(start);
}

strncmp() - Compare strings ( Limited by length ) 

strncmp()  The function is declared as follows  

int strncmp(const char *str1, const char *str2, size_t n)

str1 → The first string to compare .

str2 → The second string to compare .

n → Maximum number of characters to compare .

This function starts comparing the first character of each string . If they are equal , Then continue to execute the following pair of , Until the characters are different , Until a null character is reached at the end , Or until... In two strings num Character matching , Whichever comes first .

If the return value < 0, said str1 Less than str2.

If the return value > 0, said str2 Less than str1.

If the return value = 0, said str1 be equal to str2.

strncmp() Function code example   

Use strncpy() The function code example is as follows

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
	char str1[20];
	char str2[20];
	strcpy(str1, "Cyuyan");
	strcpy(str2, "Cyuyanyyds");
	printf("%d", strncmp(str1, str2, 6));

	return 0;
}

The operation results are as follows  

0 → representative str1 be equal to str2

If there is no string appended here, the result will be -1, because str1<str2. Just because we added the characters as 6, It can be str1 = str2.

strncat() Source code implementation

The sample code is as follows :

int __cdecl strncmp
(
    const char *first,
    const char *last,
    size_t      count
)
{
    size_t x = 0;

    if (!count)
    {
        return 0;
    }

    /*
     * This explicit guard needed to deal correctly with boundary
     * cases: strings shorter than 4 bytes and strings longer than
     * UINT_MAX-4 bytes .
     */
    if( count >= 4 )
    {
        /* unroll by four */
        for (; x < count-4; x+=4)
        {
            first+=4;
            last +=4;

            if (*(first-4) == 0 || *(first-4) != *(last-4))
            {
                return(*(unsigned char *)(first-4) - *(unsigned char *)(last-4));
            }

            if (*(first-3) == 0 || *(first-3) != *(last-3))
            {
                return(*(unsigned char *)(first-3) - *(unsigned char *)(last-3));
            }

            if (*(first-2) == 0 || *(first-2) != *(last-2))
            {
                return(*(unsigned char *)(first-2) - *(unsigned char *)(last-2));
            }

            if (*(first-1) == 0 || *(first-1) != *(last-1))
            {
                return(*(unsigned char *)(first-1) - *(unsigned char *)(last-1));
            }
        }
    }

    /* residual loop */
    for (; x < count; x++)
    {
        if (*first == 0 || *first != *last)
        {
            return(*(unsigned char *)first - *(unsigned char *)last);
        }
        first+=1;
        last+=1;
    }

    return 0;
}

strstr() - Find another string in one string

strstr() The function is declared as follows   

char *strstr(const char *haystack, const char *needle)

In string  haystack  Find the first occurrence of the string  needle  The location of , Does not contain Terminator '\0'.

haystack→  To be retrieved C character string .

needle→  stay haystack The small string to search in the string .

The function returns in haystack For the first time needle The location of the string , If not found, return null.

Be careful : The pointer type of the return value here can be void It can also be char *🧨

strstr() Function code example

subject : stay arr1 Find out whether it contains arr2 In the array . Required strstr() Library function .

Use strncpy() The function code example is as follows

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void)
{
	char arr1[20] = "abcdef";
	char arr2[20] = "bcd";
	char ret = strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf(" Did not find !\n");
	}
	else
	{
		printf(" eureka →%s\n", ret);
	}
	return 0;
}

The operation results are as follows  

eureka →bcdef

When it's not found , We put arr2 Array modification . Other values remain unchanged

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main(void)
{
	char arr1[20] = "abcdef";
	char arr2[20] = "bf";
	char *ret = strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf(" Did not find %s!\n",ret);
	}
	else
	{
		printf(" eureka →%s\n", ret);
	}
	return 0;
}

The operation results are as follows  

Can't find (null)!

In contrast , Do you see the difference

Create a custom function implementation strstr()

Analysis methods 🧐

It's really easy , We just need to compare the first character address, and if it is equal, it will return , When they are not equal, they increase automatically ++( Be careful : This is self accretion ++ It only needs str1 Conduct ++ and str2 Still compare the first element address with it ), Compare again until '\0', No null pointer is returned NULL. If str1 There are elements and str2 If the address of the first element matches, then go back ~ however , This is just an assumption abcd and bcd Applicable scenarios . If it is bbbc and bbc, What about this ? Did you find it impossible to use this idea , Let's use the code to explain how to implement .

The sample code is as follows :  

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
char *my_strstr(const char *str1, const char *str2)
{
	assert(str1 && str2 != NULL);
	const char* s1 = NULL;
	const char* s2 = NULL;// Assign a null pointer directly without knowing what to assign .
	if (*str2 == '\0')
		return (char*)str1;// hypothesis str2 If the address of the first element is an empty string, it will be returned directly str1
	while (*str1)
	{
		s1 = str1;
		s2 = str2;
		while (*s1 && *s2 != '\0' && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)str1;// Note the return type cast !
		}
		str1++;
	}
	return NULL;
}
int main(void)
{
	char arr1[20] = "abbcdef";
	char arr2[20] = "bc";
	char *ret = my_strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf(" Did not find %s!\n",ret);
	}
	else
	{
		printf(" eureka →%s\n", ret);
	}
	return 0;
}

The operation results are as follows  

bcdef 

The implementation of this code is relatively more complex than the above code , I hope you can understand and do it yourself , Because when you type the code , That's what you learned .


strtok() - Cut string

This function is difficult to understand , Quite a spectacle , Usage scenarios are also rare .

strtok() The function is declared as follows   

char * strtok ( char * str, const char * delimiters );

The sequence of calls to this function will str Split into tags , A tag is a sequence of consecutive characters , Separated by any character of the separator . 

On the first call , The function expects a C As a string of str Parameters of , Its first character is used as the starting position of the scan mark . In subsequent calls , This function expects a null pointer , And use the position after the end of the last mark as the new scanning starting position .

To determine the start and end of the tag , The function first scans the start position for the first character that is not contained in the separator ( It becomes the beginning of the tag ). Then scan the first character contained in the separator from the beginning of the tag , This character becomes the end of the tag . If a terminated null character is found , The scan will also stop .

The end of this tag is automatically replaced by a null character , The beginning of the tag is returned by the function .

Once in a strtok Found in the call str Terminated null character , All subsequent calls to this function ( Take null pointer as the first parameter ) Both return a null pointer .

Find the location of the last token and store it internally by the function , So that the next call will use ( To avoid data competition , No specific library implementation is required ).

str→ To truncate C character string . Be careful , This string is broken down into smaller strings ( token ).
perhaps , You can specify a null pointer , under these circumstances , Function continues to scan where a successful call to the function ended before .

delimiters→ Containing separator characters C character string . These may be different between different calls .

Return value : If the token is found , Pointer to the beginning of the token . otherwise , Null pointer . When the scanned string reaches the end of the string ( A null character ) when , Always return a null pointer .

strtok() Function code example

subject : Put the string "Hello.Cyuyan.yyds",. The previous statement is divided and finally printed . use strtok String function implementation .

Use strtok() The function code example is as follows

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

int main(void)
{
	char str[] = "Hello.Cyuyan.yyds";
	printf("yiduanhua|%s|dezifu\n", str);
	char * pch=strtok(str, ".");
	while (pch != NULL)
	{
		printf("%s\n", pch);
		pch = strtok(NULL, ".");
	}
	return 0;
}

The operation results are as follows  

Hello.Cyuyan.yyds

Hello

Cyuyan

yyds

I wonder if you understand ( ゚д゚)つ

Think about it here , So what does it use to save ? This is the function that remembers the address , In fact, only one keyword is needed for this static Static local variables can perfectly realize this kind of memory function , Extend the life cycle , Out of the scope of the function, the original value will not be destroyed .


strtok() Source code implementation

The sample code is as follows :  

/***
*strtok.c - tokenize a string with given delimiters
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       defines strtok() - breaks string into series of token
*       via repeated calls.
*
*******************************************************************************/

#include <cruntime.h>
#include <string.h>
#ifdef _SECURE_VERSION
#include <internal.h>
#else  /* _SECURE_VERSION */
#include <mtdll.h>
#endif  /* _SECURE_VERSION */

/***
*char *strtok(string, control) - tokenize string with delimiter in control
*
*Purpose:
*       strtok considers the string to consist of a sequence of zero or more
*       text tokens separated by spans of one or more control chars. the first
*       call, with string specified, returns a pointer to the first char of the
*       first token, and will write a null char into string immediately
*       following the returned token. subsequent calls with zero for the first
*       argument (string) will work thru the string until no tokens remain. the
*       control string may be different from call to call. when no tokens remain
*       in string a NULL pointer is returned. remember the control chars with a
*       bit map, one bit per ascii char. the null char is always a control char.
*
*Entry:
*       char *string - string to tokenize, or NULL to get next token
*       char *control - string of characters to use as delimiters
*
*Exit:
*       returns pointer to first token in string, or if string
*       was NULL, to next token
*       returns NULL when no more tokens remain.
*
*Uses:
*
*Exceptions:
*
*******************************************************************************/

#ifdef _SECURE_VERSION
#define _TOKEN *context
#else  /* _SECURE_VERSION */
#define _TOKEN ptd->_token
#endif  /* _SECURE_VERSION */

#ifdef _SECURE_VERSION
char * __cdecl strtok_s (
        char * string,
        const char * control,
        char ** context
        )
#else  /* _SECURE_VERSION */
char * __cdecl strtok (
        char * string,
        const char * control
        )
#endif  /* _SECURE_VERSION */
{
        unsigned char *str;
        const unsigned char *ctrl = control;

        unsigned char map[32];
        int count;

#ifdef _SECURE_VERSION

        /* validation section */
        _VALIDATE_RETURN(context != NULL, EINVAL, NULL);
        _VALIDATE_RETURN(string != NULL || *context != NULL, EINVAL, NULL);
        _VALIDATE_RETURN(control != NULL, EINVAL, NULL);

        /* no static storage is needed for the secure version */

#else  /* _SECURE_VERSION */

        _ptiddata ptd = _getptd();

#endif  /* _SECURE_VERSION */

        /* Clear control map */
        for (count = 0; count < 32; count++)
                map[count] = 0;

        /* Set bits in delimiter table */
        do {
                map[*ctrl >> 3] |= (1 << (*ctrl & 7));
        } while (*ctrl++);

        /* Initialize str */

        /* If string is NULL, set str to the saved
         * pointer (i.e., continue breaking tokens out of the string
         * from the last strtok call) */
        if (string)
                str = string;
        else
                str = _TOKEN;

        /* Find beginning of token (skip over leading delimiters). Note that
         * there is no token iff this loop sets str to point to the terminal
         * null (*str == '\0') */
        while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
                str++;

        string = str;

        /* Find the end of the token. If it is not the end of the string,
         * put a null there. */
        for ( ; *str ; str++ )
                if ( map[*str >> 3] & (1 << (*str & 7)) ) {
                        *str++ = '\0';
                        break;
                }

        /* Update nextoken (or the corresponding field in the per-thread data
         * structure */
        _TOKEN = str;

        /* Determine if a token has been found. */
        if ( string == str )
                return NULL;
        else
                return string;
}


strerror() - Return error code  

The function of this function is : Return error code , The corresponding error message .

strerror()  The function is declared as follows   

char * strerror ( int errnum );

Get a pointer to the error message string .

errnum Value , Generate a string , This string carries a message describing the error condition , Just like the function of the library is set to errno equally . The header file is :#include <errno.h>

The returned pointer points to a statically allocated string , This string cannot be modified by the program . Further calls to this function may overwrite its contents ( To avoid data competition , No specific library implementation is required ).

from strerror The resulting error string may be specific to each system and library implementation .

Return value : This function returns a pointer to the error string , The error string describes the error errnum.

strerror() Function code example

The open file function is :fopen()

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(void)
{
	FILE* Pf = fopen("test.txt", "r");// If the open file exists in read form, the file will fail to open !
	// If you fail to open it, you will get NULL
	if (Pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;// return main End of the function 
	}
	fclose(Pf);
	Pf = NULL;
	return 0;
}

The operation results are as follows  

Error: No such file or directory 

Of course, if you create a new one in the installation path test.txt The file will not show the above problem .

strerror() Source code implementation

The sample code is as follows :  

#include <cruntime.h>
#include <errmsg.h>
#include <stdlib.h>
#include <syserr.h>
#include <string.h>
#include <mtdll.h>
#include <tchar.h>
#include <malloc.h>
#include <stddef.h>
#include <dbgint.h>
#include <internal.h>

/* [NOTE: The error message buffer is shared by both strerror
   and _strerror so must be the max length of both. */
/* Max length of message = user_string(94)+system_string+2 */
#define _ERRMSGLEN_ (94+_SYS_MSGMAX+2)

#ifdef _UNICODE
#define _terrmsg    _werrmsg
#else  /* _UNICODE */
#define _terrmsg    _errmsg
#endif  /* _UNICODE */

/***
*char *strerror(errnum) - Map error number to error message string.
*
*Purpose:
*       The strerror runtime takes an error number for input and
*       returns the corresponding error message string.  This routine
*       conforms to the ANSI standard interface.
*
*Entry:
*       int errnum - Integer error number (corresponding to an errno value).
*
*Exit:
*       char * - Strerror returns a pointer to the error message string.
*       This string is internal to the strerror routine (i.e., not supplied
*       by the user).
*
*Exceptions:
*       None.
*
*******************************************************************************/

#ifdef _UNICODE
wchar_t * cdecl _wcserror(
#else  /* _UNICODE */
char * __cdecl strerror (
#endif  /* _UNICODE */
        int errnum
        )
{
        _TCHAR *errmsg;
        _ptiddata ptd = _getptd_noexit();
        if (!ptd)
                return _T("Visual C++ CRT: Not enough memory to complete call to strerror.");

        if ( (ptd->_terrmsg == NULL) && ((ptd->_terrmsg =
                        _calloc_crt(_ERRMSGLEN_, sizeof(_TCHAR)))
                        == NULL) )
                return _T("Visual C++ CRT: Not enough memory to complete call to strerror.");
        else
                errmsg = ptd->_terrmsg;

#ifdef _UNICODE
        _ERRCHECK(mbstowcs_s(NULL, errmsg, _ERRMSGLEN_, _get_sys_err_msg(errnum), _ERRMSGLEN_ - 1));
#else  /* _UNICODE */
        _ERRCHECK(strcpy_s(errmsg, _ERRMSGLEN_, _get_sys_err_msg(errnum)));
#endif  /* _UNICODE */

        return(errmsg);
}

/***
*errno_t strerror_s(buffer, sizeInTChars, errnum) - Map error number to error message string.
*
*Purpose:
*       The strerror_s runtime takes an error number for input and
*       copies the corresponding error message string in the destination
*       buffer. If the buffer is too small, the message is truncated.
*
*Entry:
*       TCHAR * buffer - Destination buffer.
*       size_t sizeInTChars - Size of the destination buffer.
*       int errnum - Integer error number (corresponding to an errno value).
*
*Exit:
*       The error code.
*
*Exceptions:
*       Input parameters are validated. Refer to the validation section of the function.
*
*******************************************************************************/

#ifdef _UNICODE
errno_t __cdecl _wcserror_s(
#else  /* _UNICODE */
errno_t __cdecl strerror_s(
#endif  /* _UNICODE */
        TCHAR* buffer,
        size_t sizeInTChars,
        int errnum
        )
{
        errno_t e = 0;

        /* validation section */
        _VALIDATE_RETURN_ERRCODE(buffer != NULL, EINVAL);
        _VALIDATE_RETURN_ERRCODE(sizeInTChars > 0, EINVAL);

        /* we use mbstowcs_s or strncpy_s because we want to truncate the error string
         * if the destination is not big enough
         */
#ifdef _UNICODE
        e = _ERRCHECK_EINVAL_ERANGE(mbstowcs_s(NULL, buffer, sizeInTChars, _get_sys_err_msg(errnum), _TRUNCATE));
        /* ignore the truncate information */
        if (e == STRUNCATE)
        {
                e = 0;
        }
#else  /* _UNICODE */
        _ERRCHECK(strncpy_s(buffer, sizeInTChars, _get_sys_err_msg(errnum), sizeInTChars - 1));
#endif  /* _UNICODE */
    return e;
}

Last

The use of string functions is a knowledge point that we must master. Many interview knowledge points include the application of string functions in the program , So we must understand and master this knowledge point . Although there are many knowledge points , But we still have to absorb and digest this knowledge . It's said that long pressing the collection button will surprise you ╰(*°▽°*)╯

原网站

版权声明
本文为[Chenze]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090335296606.html