C語言字符串函數(shù)與內(nèi)存函數(shù)精講
strlen
獲取字符串長度。
strlen - size_t strlen( const char *string );
1.字符串以’\0’作為結(jié)束標(biāo)志,strlen函數(shù)返回的是在字符串中’\0’前面出現(xiàn)的字符個(gè)數(shù)(不包含’\0’).
2.參數(shù)指向的字符串必須要以’\0’結(jié)束。
3.注意函數(shù)的返回值為size_t,是無符號的(易錯)

strlen模擬實(shí)現(xiàn)
//size_t strlen(const char *string);
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str != NULL);
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
int main()
{
int len = my_strlen("abcedfg");
printf("%d\n", len);
return 0;
}
strcpy
復(fù)制一個(gè)字符串
strcpy - char *strcpy( char *strDestination, const char *strSource );
1.源字符串必須以’\0’結(jié)束。
2.會將源字符串中的’\0’拷貝到目標(biāo)空間。
3.目標(biāo)空間必須足夠大,以確保存放源字符串。
4.目標(biāo)空間必須可變。
strcpy的模擬實(shí)現(xiàn)
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
//將src指向的字符串拷貝到dest指向的空間中,包括'\0'
while (*dest++ = *src++)
;
//返回目的地空間的起始地址
return ret;
}
int main()
{
//char* arr1 = "abcdefghi";//err 目標(biāo)空間必須可變
char arr1[] = "abcdefghi";
//char arr2[] = { 'h','e','l','l','o' };//err 源字符串必須以'\0'結(jié)尾
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf(arr1);
return 0;
}
strcat
字符串追加
strcat - char *strcat( char *strDestination, const char *strSource );
1.源字符串必須以’\0’結(jié)束。
2.目標(biāo)空間必須足夠大,能容納下源字符串的內(nèi)容。
3.目標(biāo)空間必須可修改。
4.不能自己給自己追加。
strcat的模擬實(shí)現(xiàn)
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, char* src)
{
char* ret = dest;
assert(dest && src);
//1.找到目的字符串中的'\0'
while (*dest)
dest++;
//2.追加
while (*dest++ = *src++)
;
return ret;
}
int main()
{
char arr1[37] = "hello";
char arr2[] = "world";
my_strcat(arr1, arr2);//在arr1后面追加arr2
printf("%s\n", arr1);
return 0;
}
strcmp
字符串比較

strcmp模擬實(shí)現(xià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;
}
int main()
{
char* p1 = "abcdef";
char* p2 = "abqjf";
int ret = my_strcmp(p1, p2);
printf("%d\n", ret);
return 0;
}
strncpy
將一個(gè)字符串中的字符復(fù)制到另一個(gè)字符串中。
strncpy - char *strncpy( char *strDest, const char *strSource, size_t count );
1.拷貝count個(gè)字符從源字符串到目標(biāo)空間。
2.如果源字符串的長度小于count,則拷貝完源字符串之后,在目標(biāo)的后邊追加0,直到count個(gè)。
strncpy模擬實(shí)現(xiàn)
char* my_strncpy(char* dest, const char* src, size_t count)
{
char* ret = dest;
while (count && (*dest++ = *src++))
{
count--;
}
if (count)
{
while (--count)
{
*dest++ = '\0';
}
}
return ret;
}
int main()
{
char arr1[20] = { 0 };
char arr2[] = "hey";
my_strncpy(arr1, arr2, 6);
printf(arr1);
return 0;
}
strncat
字符串的附加字符。
strncat - char *strncat( char *Dest, const char *Source, size_t count );
strncat模擬實(shí)現(xiàn)
char* my_strncat(char* dest, const char* src, size_t count)
{
char* ret = dest;
while (*dest++)
;
dest--;
while (count--)
{
if (!(*dest++ = *src++))
{
return ret;
}
}
*dest = '\0';
return ret;
}
int main()
{
char arr1[37] = "hello";
char arr2[] = "world";
my_strncat(arr1, arr2, 7);
puts(arr1);
return 0;
}
strncmp
比較兩個(gè)字符串的字符。
strncmp - int strncmp( const char *string1, const char *string2, size_t count );
1.比較到出現(xiàn)一個(gè)字符不一樣或者一個(gè)字符串結(jié)束或者count個(gè)字符串全部比較完。


strstr
查找子字符串
strstr - char *strstr( const char *string, const char *strCharSet );
1.每個(gè)函數(shù)都返回一個(gè)指向strCharSet在string中首次出現(xiàn)的指針,如果strCharSet沒有在string中出現(xiàn),則返回NULL。如果strCharSet指向長度為0的字符串,則函數(shù)返回string。
strstr模擬實(shí)現(xiàn)
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
char* cur = (char*)str1;
char* s1, * s2;
if (!*str2)
return ((char*)str1);
while (*cur)
{
s1 = cur;
s2 = (char*)str2;
while (*s1 && *s2 && !(*s1 - *s2))
{
s1++;
s2++;
}
if (!*s2)
return cur;
cur++;
}
return NULL;
}
int main()
{
char* p1 = "aqqqcdef";
char* p2 = "qqc";
char* ret = my_strstr(p1, p2);
if (ret == NULL)
printf("字串不存在\n");
else
printf("%s\n", ret);
return 0;
}
strtok
切割字符串,查找字符串中的下一個(gè)令牌
strtok - char * strtok ( char * str, const char * sep );
1.sep參數(shù)是個(gè)字符串,定義了用作分隔符的字符集合。
2.第一個(gè)參數(shù)指定一個(gè)字符串,它包含了0個(gè)或者多個(gè)由sep字符串中一個(gè)或者多個(gè)分隔符分割的標(biāo)記。
3.strtok函數(shù)找到str中的下一個(gè)標(biāo)記,并將其用’\0’結(jié)尾,返回一個(gè)指向這個(gè)標(biāo)記的指針。(注:strtok函數(shù)會改變被操作的字符串,所以在使用
strtok函數(shù)切分的字符串一般都是臨時(shí)拷貝的內(nèi)容并且可修改)。
4.strtok函數(shù)的第一個(gè)參數(shù)不為NULL,函數(shù)將找到str中第一個(gè)標(biāo)記,strtok函數(shù)將保存它在字符串中的位置。
5.strtok函數(shù)的第一個(gè)參數(shù)為NULL,函數(shù)將在同一個(gè)字符串中被保存的位置開始,查找下一個(gè)標(biāo)記。
6.如果字符串中不存在更多的標(biāo)記,則返回NULL指針。
int main()
{
char arr[] = "hyr@baidu.com";
char* p = "@.";
char buf[1024] = { 0 };
strcpy(buf, arr);
char* ret = NULL;
for (ret = strtok(arr, p);ret != NULL;ret = strtok(NULL, p))
{
printf("%s\n", ret);
}
return 0;
}
strerror
獲取系統(tǒng)錯誤消息(strerror)或打印用戶提供的錯誤信息。
strerror - char *strerror( int errnum );
1.返回錯誤碼所對應(yīng)的錯誤信息。
2.errno是一個(gè)全局的錯誤碼的變量,當(dāng)C語言的庫函數(shù)在執(zhí)行過程中發(fā)生了錯誤,就會把對應(yīng)的錯誤碼賦值到errno中。
#include<stdio.h>
#include<string.h>
#include<errno.h>//必須包含的頭文件
int main()
{
FILE* pf = fopen("unexist.ent", "r");
if (pf == NULL)
{
printf("Error opening file unexist.ent:%s\n", strerror(errno));
//errno: Last error number
return 0;
}
//....
return 0;
}
tolower\toupper
int tolower ( int c) ; - 大寫字母轉(zhuǎn)化為小寫字母
int toupper ( int c) ; - 小寫字母轉(zhuǎn)化為大寫字母

memcpy
在緩沖區(qū)之間復(fù)制字符
memcpy - void * memcpy ( void * dest, const void * source, size_t num );
1.函數(shù)memcpy從source的位置開始向后復(fù)制num個(gè)字節(jié)的數(shù)據(jù)到destation的內(nèi)存位置。
2.這個(gè)函數(shù)在遇到\0的時(shí)候并不會停下來。
3.如果source和destion有任何的重疊,復(fù)制的結(jié)果都是未定義的。
memcpy模擬實(shí)現(xiàn)
#include<stdio.h>
#include<assert.h>
struct Stu
{
char name[20];
int age;
};
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
while (num--)
{
*((char*)dest) = *((char*)src);
++(char*)dest;
++(char*)src;
}
return ret;
}
int main()
{
struct Stu arr1[] = { {"zhangsan",13},{"lisi",17} };
struct Stu arr2[3] = { 0 };
my_memcpy(arr2, arr1, sizeof(arr1));
return 0;
}
memmove
將一個(gè)緩沖區(qū)移動到另外一個(gè)緩沖區(qū)
memmove - void *memmove( void *dest, const void *src, size_t count );
1.和memcpy的差別就是memmove函數(shù)處理的源內(nèi)存塊和目標(biāo)內(nèi)存塊是可以重疊的。
2.如果源空間和目標(biāo)空間出現(xiàn)重疊,就得使用memmove函數(shù)處理。
memmove模擬實(shí)現(xiàn)

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t count)
{
assert(dest && src);
void* ret = dest;
if (dest < src)
{
while (count--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
}
else
{
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//將1,2,3,4,5數(shù)據(jù)拷貝到3,4,5,6,7空間上去
my_memmove(arr + 2, arr, 20);
for (int i = 0;i < 10;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
memcmp
比較兩個(gè)緩沖區(qū)間的字符
memcmp - int memcmp( const void *buf1, const void *buf2, size_t count );
1.比較從buf1和buf2指針開始的count個(gè)字節(jié)


memset
將緩沖區(qū)設(shè)定為指定的字符
menset - void *memset( void *dest, int c, size_t count );
到此這篇關(guān)于C語言字符串函數(shù)與內(nèi)存函數(shù)精講的文章就介紹到這了,更多相關(guān)C語言字符串與內(nèi)存函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語言的字符串函數(shù),內(nèi)存函數(shù)筆記詳解
- c語言重要的字符串與內(nèi)存函數(shù)
- C語言動態(tài)內(nèi)存函數(shù)詳解
- C語言超詳細(xì)講解字符串函數(shù)和內(nèi)存函數(shù)
- C語言深入詳解四大內(nèi)存函數(shù)的使用
- C語言字符串函數(shù),字符函數(shù),內(nèi)存函數(shù)使用及模擬實(shí)現(xiàn)
- 深入了解C語言中的字符串和內(nèi)存函數(shù)
- 深度解析三個(gè)常見的C語言內(nèi)存函數(shù)
- C語言內(nèi)存函數(shù)的實(shí)現(xiàn)示例
- C語言內(nèi)存函數(shù)的具體使用
相關(guān)文章
C語言驅(qū)動開發(fā)之內(nèi)核使用IO/DPC定時(shí)器詳解
本章將繼續(xù)探索驅(qū)動開發(fā)中的基礎(chǔ)部分,定時(shí)器在內(nèi)核中同樣很常用,在內(nèi)核中定時(shí)器可以使用兩種,即IO定時(shí)器,以及DPC定時(shí)器,感興趣的可以了解一下2023-04-04
C++中vector的實(shí)現(xiàn)方法示例詳解
這篇文章主要介紹了C++中vector實(shí)現(xiàn)的相關(guān)資料,vector是C++中重要的容器之一,底層通過三個(gè)迭代器實(shí)現(xiàn),分別是_start,?_finish,?和_end_of_storage,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10
解析為何要關(guān)閉數(shù)據(jù)庫連接,可不可以不關(guān)閉的問題詳解
本篇文章是對為何要關(guān)閉數(shù)據(jù)庫連接,可不可以不關(guān)閉的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05

