【C 标准库】<string.h>

2018-06-18 04:21:13来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

参考链接: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);    // 注意!
    }

  

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:serial redirection

下一篇:6.19noip模拟赛总结