zoukankan      html  css  js  c++  java
  • 【C 标准库】<string.h>

    参考链接:C 标准库 - <string.h>

    string.h中主要有两类函数:

      memxxx 和 strxxx,其中memxxx是针对内存操作的函数,在遇到''的时候并不会停下来,而通常是设置一个size_t类型(其实是unsigned int)的参数来表示字节大小;

      而strxxx是针对字符串操作的函数,遇到''停下来。strxxx函数中,有一些函数是strnxxx的,这些函数可以通过传入一个size_t类型的参数来表示字节大小,所以遇到''或到达字节大小都会停下来,相对安全。

    以下分组介绍函数:

    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);
     
    // 内存拷贝。当拷贝字符串的时候,考虑到''的问题,可以这样拷贝进str1。此时如果str2中有,拷贝动作仍然会进行下去,直到达到n次
    memcpy(str1, str2, sizeof(str1) - 1);
    str1[sizeof(str1) - 1] = '';
    // 遇到内存重叠的情况,memmove是更安全的,不会造成覆盖的情况
    // http://stackoverflow.com/questions/4415910/memcpy-vs-memmove
    char str5[] = "aabbcc";
    printf( "The string: %s
    ", str5 );
    memcpy( str5, str5 + 2, 4 );    // cccccc , wrong
    printf( "New string: %s
    ", str5 );
    
    strncpy( str5, "aabbcc", sizeof(str5) );   // reset string
    
    printf( "The string: %s
    ", str5 );
    memmove( str5, str5 + 2, 4 );   // bbcccc , right
    printf( "New string: %s
    ", str5 );
    
    
    // 字符串拷贝。同理,strncpy也是如此。不过memcpy不考虑中间遇到''的问题,而strncpy遇到就停止拷贝
    ret = strncpy(str1, str2, sizeof(str1) - 1);
    str1[sizeof(str1) - 1] = '';
    // 如果str1的空间不足以放下str2,就会造成内存溢出
    ret = strcpy(str1, str2);
    

      

    2、memcmp strcmp strncmp

    stackoverflow里有个回答举例很详细:what-is-the-difference-between-memcmp-strcmp-and-strncmp-in-c

    strcmp 比较的是以'' 结束的字符串

    strncmp 比较的是至多n个字符、以''结束的字符串

    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";  // extra null bytes at end
        const char s2[] = "atomsabc";     // embedded null byte
        const char s3[] = "atomsaaa";
    
        if(strcmp(s1, s2) == 0){printf("strcmp(s1, s2) == 0 
    ");}      // strcmp stops at null terminator
        if(strcmp(s1, s3) != 0){printf("strcmp(s1, s3) != 0 
    ");}      // Strings are different
        if(strncmp(s1, s3, 5) == 0){printf("strncmp(s1, s3, 5) == 0 
    ");}  // First 5 characters of strings are the same
        if(memcmp(s1, s3, 5) == 0){printf("memcmp(s1, s3, 5) == 0 
    ");}   // First 5 bytes are the same
        if(strncmp(s1, s2, 8) == 0){printf("strncmp(s1, s2, 8) == 0 
    ");}  // Strings are the same up through the null terminator
        if(memcmp(s1, s2, 8) != 0){printf("memcmp(s1, s2, 8) != 0 
    ");}   // 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 
    ", &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 
    ", strres);
    

      

    6、strlen strnlen

    strlen 计算字符串的长度,直到空结束字符,但不包含空结束字符

    strnlen 以上函数不安全,如果字符串非法(不包含''),所以需要规定最大匹配长度,防止内存溢出

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

      

        const char strlenres[] = "test strlen";
        printf("strlen = %d 
    ", (int)strlen(strlenres));
        // 如果string没有的时候,会判断出错
        printf("strnlen = %d 
    ", (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 
    ", strcat(cat1, cat2));
        printf("res2 = %s 
    ", strncat(cat1, cat2, sizeof(cat1) - 1 - strlen(cat1)));
        printf("res3 = %s 
    ", 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 
    ", token);
            token = strtok(NULL, delim);    // 注意!
        }
    

      

  • 相关阅读:
    文本设置超过几行显示...
    CSS内置的几个标准的伪类和伪对象
    正则替换URL地址为链接地址
    移动端某些机型touchend事件触发鸡肋
    zepto 扩展prevAll(),nextAll()方法
    火狐下window.event获取undefined问题
    哪些情况下margin-left和padding-left无效?
    兵部-2048
    HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准。HTML 的上一个版本诞生于 1999 年。自从那以后,Web 世界已经经历了巨变。HTML5 仍处于完善之中。然而,大部分现代浏览器已经具备了某些 HTML5 支持。
    二分查找
  • 原文地址:https://www.cnblogs.com/tyrus/p/c_string.html
Copyright © 2011-2022 走看看