程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 【C 標准庫】<string.h>,標准庫string.h

【C 標准庫】<string.h>,標准庫string.h

編輯:關於C語言

【C 標准庫】<string.h>,標准庫string.h


參考鏈接:C 標准庫 - <string.h>

string.h中主要有兩類函數:

  memxxx 和 strxxx,其中memxxx是針對內存操作的函數,在遇到'\0'的時候並不會停下來,而通常是設置一個size_t類型(其實是unsigned int)的參數來表示字節大小;

  而strxxx是針對字符串操作的函數,遇到'\0'停下來。strxxx函數中,有一些函數是strnxxx的,這些函數可以通過傳入一個size_t類型的參數來表示字節大小,所以遇到'\0'或到達字節大小都會停下來,相對安全。

 

以下分組介紹函數:

1、memcpy memmove strcpy strncpy

void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
 
// 內存拷貝。當拷貝字符串的時候,考慮到'\0'的問題,可以這樣拷貝進str1。此時如果str2中有\0,拷貝動作仍然會進行下去,直到達到n次
memcpy(str1, str2, sizeof(str1) - 1);
str1[sizeof(str1) - 1] = '\0';
// 遇到內存重疊的情況,memmove是更安全的,不會造成覆蓋的情況
// http://stackoverflow.com/questions/4415910/memcpy-vs-memmove
char str5[] = "aabbcc";
printf( "The string: %s\n", str5 );
memcpy( str5, str5 + 2, 4 );    // cccccc , wrong
printf( "New string: %s\n", str5 );

strncpy( str5, "aabbcc", sizeof(str5) );   // reset string

printf( "The string: %s\n", str5 );
memmove( str5, str5 + 2, 4 );   // bbcccc , right
printf( "New string: %s\n", str5 );


// 字符串拷貝。同理,strncpy也是如此。不過memcpy不考慮中間遇到'\0'的問題,而strncpy遇到\0就停止拷貝
ret = strncpy(str1, str2, sizeof(str1) - 1);
str1[sizeof(str1) - 1] = '\0';
// 如果str1的空間不足以放下str2,就會造成內存溢出
ret = strcpy(str1, str2);

  

2、memcmp strcmp strncmp

stackoverflow裡有個回答舉例很詳細:what-is-the-difference-between-memcmp-strcmp-and-strncmp-in-c

strcmp 比較的是以'\0' 結束的字符串

strncmp 比較的是至多n個字符、以'\0'結束的字符串

memcmp 比較的是n個字節的二進制字節緩沖區

void *memcpy(void *dest, const void *src, size_t n);
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);

 

    const char s1[] = "atoms\0\0\0\0";  // extra null bytes at end
    const char s2[] = "atoms\0abc";     // embedded null byte
    const char s3[] = "atomsaaa";

    if(strcmp(s1, s2) == 0){printf("strcmp(s1, s2) == 0 \n");}      // strcmp stops at null terminator
    if(strcmp(s1, s3) != 0){printf("strcmp(s1, s3) != 0 \n");}      // Strings are different
    if(strncmp(s1, s3, 5) == 0){printf("strncmp(s1, s3, 5) == 0 \n");}  // First 5 characters of strings are the same
    if(memcmp(s1, s3, 5) == 0){printf("memcmp(s1, s3, 5) == 0 \n");}   // First 5 bytes are the same
    if(strncmp(s1, s2, 8) == 0){printf("strncmp(s1, s2, 8) == 0 \n");}  // Strings are the same up through the null terminator
    if(memcmp(s1, s2, 8) != 0){printf("memcmp(s1, s2, 8) != 0 \n");}   // First 8 bytes are different

  

3、memchr strchr strrchr

memchr 在內存中,從某個地址開始到n個字節之後,返回最早匹配到的字符的指針

strchr 在一個字符串中,返回最早匹配到的字符的指針

strrchr 在一個字符串中,返回最後一個匹配到的字符的指針

void *memchr(const void *str, int c, size_t n);
char *strchr(const char *str, int c);
char *strrchr(const char *str, int c);

  

    char chr[] = "there is an orange";
    const char *memchrres = memchr(chr, 'r', 12); // 中間的int型參數其實需要傳入char型的字符。。
    const char *strchrres = strchr(chr, 'r');
    const char *strrchrres = strrchr(chr, 'r');
    printf("memchrres:(%p) %s, strchrres:(%p) %s, strrchrres:(%p) %s \n", &memchrres, memchrres, &strchrres, strchrres, &strrchrres, strrchrres);

  

4、memset:將s所指向的某一塊內存中的前n個 字節的內容全部設置為ch指定的ASCII值, 第一個值為指定的內存地址,塊的大小由第三個參數指定,這個函數通常為新申請的內存做初始化工作, 其返回值為指向s的指針(摘自 百度百科)

void *memset(void *str, int c, size_t n);

  

struct S abc;
memset(&abc, 0, sizeof(struct S));

 

5、strstr:在字符串 haystack 中查找第一次出現字符串 needle(不包含空結束字符)的位置。

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

  

    const char haystack[20] = "W3CSchool lalala";
    const char needle[10] = "School";
    char *strres;
    strres = strstr(haystack, needle);
    printf("%s \n", strres);

  

6、strlen strnlen

strlen 計算字符串的長度,直到空結束字符,但不包含空結束字符

strnlen 以上函數不安全,如果字符串非法(不包含'\0'),所以需要規定最大匹配長度,防止內存溢出

size_t strlen(const char *str);
size_t strnlen(const char *str, size_t maxlen);

  

    const char strlenres[] = "test strlen";
    printf("strlen = %d \n", (int)strlen(strlenres));
    // 如果string沒有\0的時候,會判斷出錯
    printf("strnlen = %d \n", (int)strnlen(strlenres, sizeof(strlenres)));

  

7、strcat strncat

strcat 把源字符串追加到目標字符串的後面

strncat 規定最大追加數n,相對安全

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

  

    char cat1[20] = "lalala";
    char cat2[] = "short";
    char cat3[] = "longlong";
    printf("res1 = %s \n", strcat(cat1, cat2));
    printf("res2 = %s \n", strncat(cat1, cat2, sizeof(cat1) - 1 - strlen(cat1)));
    printf("res3 = %s \n", strncat(cat1, cat3, sizeof(cat1) - 1 - strlen(cat1)));

  

8、strtok:根據給定的分隔符,分割一個長的字符串(使用方法很怪異。。)

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

  

    char tok[80] = "This is - www.w3cschool.cc - website";
    const char delim[] = "-";
    char *token = strtok(tok, delim);   // 獲取第一個字符串
    while(token != NULL){
        printf("%s \n", token);
        token = strtok(NULL, delim);    // 注意!
    }

  

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved