content
strcmp simulation implementation
strcat simulation implementation
strcpy simulation implementation
strstr simulation implementation
strncmp simulation implementation
strncat simulation implementation
strncpy simulation implementation
Simulate the implementation of memcpy
Analog implementation of memmove
Simulate the implementation of memcmp
Purpose of this chapter:
Simulate string functions: strlen, strcmp, strcat, strcpy, strstr, strncmp, strncat, strncpy
Introduce the use of strtok and strerror
Simulate memory functions: memcpy, memmove, memset, memcmp
strlen mock implementation
size_t my_strlen(const char* str)
{
assert(str);
if (*str == '\0')
{
return 0;
}
return 1 + strlen(str + 1);
}
strcmp simulation implementation
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;
}
strcat simulation implementation
char* my_strcat(char* dest,const char* sour)
{
char* ret = dest;
assert(dest && sour);
while (*dest)
{
dest++;
}
while (*dest++ = *sour++)
{
;
}
return ret;
}
In short:
Find the '\0' of the target string, then copy the source string (including the end mark of the source string), and return the starting address of the target string.
strcpy simulation implementation
char* my_strcpy(char* dest,const char* sour)
{
char* ret = dest;
assert(dest && sour);
while (*dest++=*sour++)
{
;
}
return ret;
}
strstr simulation implementation
char* my_strstr(char* str,const char* substr)
{
char* cur = str;
assert(str && substr);
while (*cur)
{
char* s1 = cur;
char* s2 = (char*)substr;
while (*s1 == *s2 && *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cur;
}
cur++;
}
return NULL;
}
strncmp simulation implementation
int my_strncmp(const char* str1,const char* str2,int n)
{
assert(str1 && str2);
while (*str1 == *str2 && n > 0)
{
n--;
str1++;
str2++;
}
if (n == 0)
{
return 0;
}
return *str1 - *str2;
}
strncat simulation implementation
char* my_strncat(char* dest,const char* sour,int n)
{
char* ret = dest;
assert(dest && sour);
while (*dest)
{
dest++;
}
while (n--)
{
*dest++ = *sour++;
}
return ret;
}
strncpy simulation implementation
char* my_strncpy(char* dest,const char* sour,int n)
{
char* ret = dest;
assert(dest && sour);
while (n--)
{
*dest++ = *sour++;
}
return ret;
}
Introducing strtok
The strtok function can achieve the effect of splitting strings with certain symbols
If you want to extract "hello", "world", "name", "apple" strings from "[email protected]#apple", you can use strtok, where "[email protected]" is the destination string , "@.#" is the set of separators.
The first parameter strToken is the string to be divided, and the second parameter strDelimit is the set of delimiters.
About the return value of strtok
Translation: All these functions return a pointer to the next token found in strToken. They return NULL when no more tokens are found. Each call modifies strToken by replacing each delimiter encountered with a null character.
The strtok function finds the next token in str, ends it with \0, and returns a pointer to this token. Therefore, the strtok function will change the manipulated string, so the string segmented by the strtok function is generally the content of a temporary copy
and can be modified. )
The first parameter of the strtok function is not NULL, the function will find the first token in str, and the strtok function will save its
position in the string.
The first argument to the strtok function is NULL, and the function will start at the saved position in the same string and look for the next
token.
If there are no more tokens in the string, a NULL pointer is returned.
Here is the code to separate "hello", "world", "name", "apple" from "[email protected]#apple"
Introducing strerror
This function is relatively simple to use, prints the corresponding error message according to the passed error code, and returns a character pointer.
Error codes can be 0, 1, 2, 3, 4, 5, 6, etc.
Such as:
In practice, it is used with errno (a global variable) in most cases
The global variable errno will automatically change its error code with the program error, so we usually use strerror(errno) to print the error message.
Note the header file reference, the header file for errno is errno.h and the header file for strerror is string.h
scenes to be used:
Simulate the implementation of memcpy
void* my_memcpy(void* dest, const void* sour,int num)
{
assert(dest && sour);
void* ret= dest;
while (num--)
{
*(char*)dest = *(char*)sour;
dest = (char*)dest + 1;
sour = (char*)sour + 1;
}
return ret;
}
Analog implementation of memmove
void* my_memcpy(void* dest, const void* sour,int num)
{
assert(dest && sour);
void ret = dest;
if (dest < sour)
{
while (num--)
{
*(char*)dest = *(char*)sour;
dest = (char*)dest + 1;
sour = (char*)sour + 1;
}
}
else
{
while (num--)
{
*((char*)dest+num) = *((char*)sour+num);
}
}
return ret;
}
The same point, memmove and memcpy have basically the same functions, and both can copy memory in bytes.
Difference: memmove() can copy overlapping memory,
The memcpy() c standard does not require that it be done copying overlapping memory. vs2019memcpy() can copy overlapping memory.
Mock implementation of memset
void* my_memset(void* dest, int c, size_t count)
{
assert(dest);
void* ret = dest;
while (count--)
{
*(char*)dest = (char)c;
dest = (char*)dest + 1;
}
return ret;
}
Simulate the implementation of memcmp
int my_memcmp(const void* str1, const void* str2,int num)
{
assert(str1 && str2);
while (*(char*)str1 == *(char*)str2 && num>0)
{
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
num--;
}
if (num == 0)
{
return 0;
}
else if (*(char*)str1 > *(char*)str2)
{
return 1;
}
else
{
return -1;
}
}
At last
If you have any questions about this chapter, please feel free to communicate with me.
If there is an error in this chapter, please point it out, I am very grateful.
If you find it useful, please like and comment, thank you.