目錄
7. strncat函數的使⽤
8. strncpy函數的使⽤
9. strncmp函數的使⽤
10. strstr的使⽤和模擬實現
11. strtok函數的使⽤
12. strerror函數的使⽤
7. strncat 函數的使⽤
函數原型如下:
char * strncat ( char * destination, const char * source, size_t num );
注意:
- 將source指向字符串的前num個字符追加到destination指向的字符串末尾,再追加⼀個 符)。 \0 字
- 如果source 指向的字符串的⻓度⼩於num的時候,只會將字符串中到 \0 的內容追加到destination指向的字符串末尾
int main()
{
char arr1[] = "abcdef";
char arr2[20] = "xxxxxxxxxxx";
//char arr2[20] = "xx\0xxxxxxxx"; //如果數之間加了個\0,追加從\0包括\0,開始追加,即會把\0替換掉
strncat(arr2, arr1, 8); //追加8個數,不夠的用\0填補
printf("%s\n", arr2);
return 0;
}
輸出結果:
如果數之間加了個\0,追加從\0包括\0,開始追加,即會把\0替換掉
代碼如下:
int main()
{
char arr1[] = "abcdef";
//char arr2[20] = "xxxxxxxxxxx";
char arr2[20] = "xx\0xxxxxxxx"; //如果數之間加了個\0,追加從\0包括\0,開始追加,即會把\0替換掉
strncat(arr2, arr1, 8); //追加8個數,不夠的用\0填補
printf("%s\n", arr2);
return 0;
}
輸出結果:
8. strncpy 函數的使⽤
函數原型:
char * strncpy ( char * destination, const char * source, size_t num );
注意:
- 拷⻉num個字符從源字符串到⽬標空間。
- 如果源字符串的⻓度⼩於num,則拷⻉完源字符串之後,在⽬標的後邊追加0,直到num個
拷貝8個數據
int main()
{
char arr1[] = "abcdef";
char arr2[] = "xxxxxxxxx";
//strncpy(arr2,arr1,3); //這裏的3是,只會拷貝arr1裏面的前三個數,\0也不會算進去,是3個,就是3個
strncpy(arr2, arr1, 8); //這裏的8顯然超過了arr1裏面的數,但是我們還是會拷貝8個數,不夠的用\0來填補
printf("%s\n", arr2);
return 0;
}
輸出結果:
拷貝3個數據
int main()
{
char arr1[] = "abcdef";
char arr2[] = "xxxxxxxxx";
strncpy(arr2,arr1,3); //這裏的3是,只會拷貝arr1裏面的前三個數,\0也不會算進去,是3個,就是3個
//strncpy(arr2, arr1, 8); //這裏的8顯然超過了arr1裏面的數,但是我們還是會拷貝8個數,不夠的用\0來填補
printf("%s\n", arr2);
return 0;
}
輸出結果:
9. strncmp函數的使⽤
函數原型如下:
int strncmp ( const char * str1, const char * str2, size_t num );
⽐較str1和str2的前num個字符,如果相等就繼續往後⽐較,最多⽐較num個字⺟,如果提前發現不⼀ 樣,就提前結束,⼤的字符所在的字符串⼤於另外⼀個。如果num個字符都相等,就是相等返回0.
代碼如下:
只設置3個比較數
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcq";
int ret = strncmp(arr1, arr2,3); //只和前3個數繼續比較大小
printf("%d\n", ret);
return 0;
}
輸出結果:
設置4個數,代碼如下:
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcq";
int ret = strncmp(arr1, arr2,4); //只和前3個數繼續比較大小
printf("%d\n", ret);
return 0;
}
輸出結果:
10. strstr 的使⽤和模擬實現
10.1 strstr的使用
函數原型:
char * strstr ( const char * str1, const char * str2);
注意:
- 函數返回字符串str2在字符串str1中第⼀次出現的位置
- 字符 串的⽐較匹配不包含 \0 字符,以 \0 作為結束標誌
代碼如下:
int main()
{
char arr1[] = "this is an apple\n";
char arr2[] = "is"; //如果沒有找到,默認的返回值是空指針,NULL
char* ret = strstr(arr1, arr2); //從遇到的第一個is開始
if (ret != NULL)
{
printf("%s\n", ret);
}
else
{
printf("沒有找到\n");
}
return 0;
}
輸出結果:
如果我們尋找arr1之外的數,那麼機會找不到
這裏我們輸入AS,在arr1裏面找這個AS,結果我們發現,沒有找到
代碼如下:
int main()
{
char arr1[] = "this is an apple\n";
char arr2[] = "AS"; //如果沒有找到,默認的返回值是空指針,NULL
char* ret = strstr(arr1, arr2); //從遇到的第一個is開始
if (ret != NULL)
{
printf("%s\n", ret);
}
else
{
printf("沒有找到\n");
}
return 0;
}
輸出結果:
10.2 strstr模擬實現
char* my_strstr(const char* str1, const char* str2)
{
const char* s1 = NULL;
const char* s2 = NULL;
const char* cur = str1;
if (*str2 == '\0')
{
return (char*)str1;
}
while (*cur)
{
s1 = cur;
s2 = str2;
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)cur;
}
cur++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdefabcdef";
char arr2[] = "cdef";
char* ret = my_strstr(arr1, arr2);
if (ret != NULL)
{
printf("%s\n", ret);
}
else
{
printf("找不到\n");
}
return 0;
}
輸出結果:
解析這個代碼:
1.主程序入口
arr1初始化為"abcdefabcdef"(末尾隱含'\0')。arr2初始化為"cdef"。- 調用
my_strstr(arr1, arr2),在arr1中查找arr2第一次出現的位置。
2.my_strstr 函數
第一次調用時:
str1→"abcdefabcdef"str2→"cdef"*str2 == 'c',所以不進入第一個 if。cur初始指向str1的第一個字符'a'。
外層循環第一次迭代:
cur → 'a'(地址 &arr1[0])
s1 = cur → 指向 'a's2 = str2 → 指向 'c'
內層 while 條件:
*s1 = 'a', *s2 = 'c','a' == 'c' 為假,不進入內層循環。
檢查 *s2 == '\0'?否,cur++ 指向 'b'。
外層循環第二次迭代:
cur → 'b's1 = cur → 'b's2 = str2 → 'c''b' == 'c' 為假,內層不執行。
cur++ 指向 'c'。
外層循環第三次迭代:
cur → 'c'(&arr1[2])
s1 = cur → 'c's2 = str2 → 'c'*s1 == *s2 為真,進入內層循環:
- 內層第一次:
s1++→'d',s2++→'d',相等,繼續。 - 內層第二次:
s1++→'e',s2++→'e',相等,繼續。 - 內層第三次:
s1++→'f',s2++→'f',相等,繼續。 - 內層第四次:
s2++後指向'\0',*s2 == '\0',內層循環條件*s2 != '\0'為假,退出內層循環
檢查 *s2 == '\0':是,説明 str2 全部匹配成功。
返回 (char*)cur,即 arr1 中 "cdefabcdef" 的起始地址。
3. 回到主函數
ret 指向 arr1 中 "cdefabcdef" 的位置。
ret != NULL 為真,執行 printf("%s\n", ret),輸出:
cdefabcdef
11. strtok函數的使⽤
函數原型:
char * strtok ( char * str, const char * sep);
注意:
- sep參數指向⼀個字符串,定義了⽤作分隔符的字符集合
- 第⼀個參數指定⼀個字符串,它包含了0個或者多個由sep字符串中⼀個或者多個分隔符分割的標 記。
- •strtok函數找到str中的下⼀個標記,並將其⽤ \0 結尾,返回⼀個指向這個標記的指針。(注: strtok函數會改變被操作的字符串,所以被strtok函數切分的字符串⼀般都是臨時拷⻉的內容並且 可修改。)
- strtok函數的第⼀個參數不為 中的位置。 NULL ,函數將找到str中第⼀個標記,strtok函數將保存它在字符串
- strtok函數的第⼀個參數為 NULL ,函數將在同⼀個字符串中被保存的位置開始,查找下⼀個標 記。
- 如果字符串中不存在更多的標記,則返回 NULL 指針。
int main()
{
char arr1[] = "zixiaolong@yeah.net";
char arr2[100] = { 0 };
strcpy(arr2, arr1);//拷貝一個臨時的數據
const char* sep = ".@"; //分割符
char* ret = NULL;
for (ret = strtok(arr2, sep); ret != NULL; ret = strtok(NULL, sep))
{
printf("%s\n", ret);
}
return 0;
}
輸出結果:
12. strerror 函數的使⽤
函數原型:
char* strerror ( int errnum )
strerror 函數可以把參數部分錯誤碼對應的錯誤信息的字符串地址返回來。
在不同的系統和C語⾔標準庫的實現中都規定了⼀些錯誤碼,⼀般是放在 errno.h
代碼如下:
int main()
{
int i = 0;
for (i = 0; i <= 10; i++)
{
printf("%d: %s\n", i, strerror(i));
}
return 0;
}
輸出結果:
以上就是我們字符串函數和字符函數的全部內容了