字符串 几个常用的字符串处理函数

  • strlen 用来求一个字符串的长度

NAME
       strlen - calculate the length of a string
​
SYNOPSIS
       #include <string.h>
​
       size_t strlen(const char *s);
​
DESCRIPTION
       The  strlen()  function calculates the length of the string pointed to by s, excluding the terminating
       null byte ('\0').
​
RETURN VALUE
       The strlen() function returns the number of characters in the string pointed to by s.
​

例子:

    int l;
    l = strlen("abcde");
    l = 5
​
    char s[10] = {"abc"};
    l = strlen(s);
    l = 3
    sizeof(s) = 10;
​
    strlen: 是一个函数,用来计算一个字符串的长度,算到第一个\0为止
    sizeof: 是一个运算符,用来求一个对象(或类型)自己本身所占内存的字节数
​
    char s1[4] = {'1', '0'};
    sizeof(s1) = 4
    l = strlen(s1);
    l = 2
​
    char s2[4] = {'1', 0, '3'};
    l = strlen(s2);
    l = 1
​
    l = strlen("abcd\123456\0ef");
    l = 8   \123 算一个字符。
  • strcpy 字符串拷贝函数 cpy: copy

​
NAME
       strcpy - copy a string
​
SYNOPSIS
       #include <string.h>
​
        strcpy用来把src指向的字符串,拷贝到dest指向的空间中去。拷贝到\0为止(\0也会拷贝)
       char *strcpy(char *dest, const char *src);
            dest: 指向“目的地”,dest指向的空间,要保证可写,并且空间要足够大。
            src: 指向“源字符串”,把src指向的字符串拷贝到dest指向的空间中去。
        返回值:
            成功 返回拷贝后字符串的首地址(dest)
​
        strcpy有一个巨大的bug:
          它没有考虑到越界的问题,有可能会导致内存越界访问或非法访问。
​
​
        strncpy就是为了解决strcpy的bug而产生的。
            strncpy用来把src指向的字符串拷贝到dest指向的空间中去。
            但是strncpy顶多拷贝n个字符(一般来说,n为dest指向的空间的最大容量)
            那么strncpy到底拷贝了多少个字符呢? <= n
            (1) 遇到\0拷贝结束(此时后面会多拷贝 n-strlen(src) 个\0)
            (2) 一直没有遇到\0,但是已经拷贝n个字符啦,拷贝结束(此时\0不会拷贝)
           char *strncpy(char *dest, const char *src, size_t n);
                dest: 指向目标空间
                src: 指向源字符串
                n: 规定拷贝n个字节。一般来说,n为dest指向的空间的最大容量
            返回值:
             成功 返回拷贝后字符串的首地址(dest)
​
          标准C库中strncpy类似实现如下:
           char* strncpy(char *dest, const char *src, size_t n)
           {
               size_t i;
​
               for (i = 0; i < n && src[i] != '\0'; i++)
                   dest[i] = src[i];
               for ( ; i < n; i++)
                   dest[i] = '\0';
​
               return dest;
           }
​

来个例子:

    char s[2];
    strcpy(s, "ab"); 
        // 有问题了,s指向的空间太小啦
        // "非法的内存访问"
​
    char *s = "abcde";
    strcpy(s, "ABC");  // 
                //有问题。 s指向的空间是  只读
                // "非法的内存访问" =》 “段错误”
​
​
  • memcpy 内存拷贝

NAME
       memcpy - copy memory area
​
SYNOPSIS
       #include <string.h>
​
        memcpy用来把src指向的内存中的前面n个字节,拷贝到dest指向的空间中去
       void *memcpy(void *dest, const void *src, size_t n);
            dest: 指向目标内存块,要保证dest指向的空间足够大
            src : 指向源内存块
            n   : 要拷贝的字节数
          返回值:
            返回dest的这个地址
​
DESCRIPTION
       The memcpy() function copies n bytes from memory area src to memory area dest.  The memory areas must not overlap.  Use memmove(3) if the memory areas do overlap.
​
RETURN VALUE
       The memcpy() function returns a pointer to dest.
​

思考: strncpy 和 memcpy 有什么区别?

strncpy是字符串拷贝函数,顶多拷贝n个字节(遇到\0拷贝结束,多补几个n-i个\0) memcpy是内存块拷贝函数(没有类型的概念),成功的话,一定会拷贝n个字节。

so, 字符串拷贝,最好用 strncpy 其他内存块拷贝,用memcpy

一个例子:

    char s1[8];
    char s2[8];
    scanf("%s", s2);
        //从键盘上输入一个字符串(遇到\n),存放到s2指向的空间中去,
        // 最后加一个\0到s2这个空间
​
        //用户输入的字符串长度不定
    
    //要把s2指向的字符串,拷贝s1   
​
    memcpy(s1, s2, strlen(s2) + 1) ; 
            // strlen(s2) + 1 <= 8 没有问题
            // strlen(s2) + 1 > 8 就有问题啦,越界啦
            //"+1" 我想把s2这个字符串后面的\0也拷贝
 
    strncpy(s1, s2, 8);
            // strlen(s2) < 8 可以完整的拷贝字符串到s1
            // strlen(s2) >= 9, 也不至于越界,因为顶多拷贝8个。
  • bzero 把一个字符串清0

​
NAME
       bzero- zero a byte string
​
SYNOPSIS
       #include <strings.h>
​
        bzero用来把s指向的空间的前面n个字节清0
       void   bzero(void *s, size_t n);
​
​
  • strcat/strncat 连接两个字符串

NAME
       strcat, strncat - concatenate(连接) two strings
​
SYNOPSIS
       #include <string.h>
​
        strcat用把src指向的字符串,连接到dest指向的字符串的末尾去。 “尾部连接”
         strcat先找到dest指向的那个字符串的末尾(\0处),从\0处开始连接src
        指向的字符串,最后加一个\0
       char *strcat(char *dest, const char *src);
            dest: 指向目标字符串,其空间应该要足够大
                    why? 如果不足够大,就有越界的风险
            src: 指向原始字符串
        返回值:
            返回连接后的字符串的首地址(dest)
       
        strcat 也有一个bug,没有考虑到dest指向的空间,是否足够大的问题
        有越界的风险。
​
        strncat就是用来修复strcat这个bug的
        strncat也是把src指向的字符串拷贝到dest的末尾,
        但是它顶多拷贝n个字符。
            (1)遇到\0拷贝结束  <=n
            (2) 即使没有遇到\0,但是已经拷贝了n个字符啦,也结束(此时\0不会拷贝)
       char *strncat(char *dest, const char *src, size_t n);
​
           A simple implementation of strncat() might be:
​
           char *
           strncat(char *dest, const char *src, size_t n)
           {
               size_t dest_len = strlen(dest);
               size_t i;
​
               for (i = 0 ; i < n && src[i] != '\0' ; i++)
                   dest[dest_len + i] = src[i];
               dest[dest_len + i] = '\0';
​
               return dest;
           }
​
  • strcmp/strncmp 比较两个字符 str: string字符串 cmp: compbare 比较 strcmp 是字符串比较函数 两个字符串如何比较呢? 一个一个字符的PK,PK它们的ASCII码

    while (第一个字符串没有结束  || 第二个字符串没有结束)
    {
        if 第一个字符串的第i字符 < 第二个字符串的第i个字符
            return -1; //表示第一个字符串 小
        else if 第一个字符串的第i字符 > 第二个字符串的第i个字符
            return 1; //表示第一个字符串 大
        else //第一个字符串的第i个字符 == 第二个字符串的第i个字符
           i++ ; 比较下一个 
    }
​
    return 0; //表示两个字符串相等,一模一样
​
NAME
       strcmp, strncmp - compare two strings
​
SYNOPSIS
       #include <string.h>
​
       int strcmp(const char *s1, const char *s2);
​
​
        strncmp只比较前面n个字符
       int strncmp(const char *s1, const char *s2, size_t n);
​
​

例子:

    int m = strcmp("123", "ABC");
        m < 0
​
    m = strcmp("123", "123\0abc");
        m == 0
​
    m = strcmp("1234", "123");
        m > 0
​
    m = strncmp("123", "12345", 3);
        m == 0

上一篇:SimpleITK 和 Nibabel 读取医学图像 nii 数据(2D显示)


下一篇:Android ORM 框架 GreenDao 使用详解,Android攒了一个月的面试题及解答