内存及字符串操作篇

bcmp

比较内存内容

头文件

#include <string.h>

函数原型

int bcmp(const void *s1, const void *s2, size_t n);
  • 说明:bcmp() 用来比较 s1 和 s2 所指的内存区间前 n 个字节,若参数 n 为 0,则返回 0。

  • 返回值:若参数 s1 和 s2 所指的内存内容都完全相同则返回 0 值,否则返回非零值。

  • 附加说明:建议使用 memcmp() 取代。

  • 相关函数:bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp

示例

参考 memcmp()

bcopy

拷贝内存内容

头文件

#include <string.h>

函数原型

void bcopy(const void *src, void *dest, size_t n);
  • 说明:bcopy() 和 memcpy() 一样都是用来拷贝 src 所指的内存内容前 n 个字节到 dest 所指的地址,不过参数 src 与 dest 在传给函数时是相反的位置。

  • 返回值:无

  • 附加说明:建议使用 memcpy() 取代。

  • 相关函数:memccpy,memcpy,memmove,strcpy,ctrncpy

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char dest[30] = "string(a)";
    char src[30]="string\0string";
    int i;
    bcopy(src, dest, 30);      /* src指针放在前面 */
    printf("bcopy(): ");
    for(i=0; i<30; i++)
        printf("%c", dest[i]);
    
    memcpy(dest, src, 30);     /* dest指针放在前面 */
    printf("\nmemcpy(): ");
    for(i=0; i<30; i++)
        printf("%c", dest[i]);
    
    return 0;
}

执行

bcopy(): stringstring
memcpy(): stringstring

bzero

将一段内存内容全清为零

头文件

#include <string.h>

函数原型

void bzero(void *s, size_t n);
  • 说明:bzero() 会将参数 s 所指的内存区域前 n 个字节,全部设为零值。相当于调用 memset((void*)s, 0, size_tn)

  • 返回值:无

  • 附加说明:bzero 不是标准库函数,为了提高可移植性,建议使用 memset 取代。

  • 相关函数:memset,swab

示例

参考 memset()

index

查找字符串中第一个出现的指定字符

头文件

#include <string.h>

函数原型

char *index(const char *s, int c);
  • 说明:index() 用来找出参数 s 字符串中第一个出现的参数 c 地址,然后将该字符出现的地址返回。字符串结束字符(NULL)也视为字符串一部分。

  • 返回值:如果找到指定的字符则返回该字符所在地址,否则返回 NULL。

  • 相关函数:rindex,srechr,strrchr

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *s = "0123456789012345678901234567890";
    char *p;
    p = index(s, '5');
    printf("%s\n", p);
    return 0;
}

执行

56789012345678901234567890

memccpy

拷贝内存内容

头文件

#include <string.h>

函数原型

void *memccpy(void *dest, const void *src, int c, size_t n);
  • 说明:memccpy() 用来拷贝 src 所指的内存内容前 n 个字节到 dest 所指的地址上。与 memcpy() 不同的是,memccpy() 会在复制时检查参数 c 是否出现,若是则返回 dest 中值为 c 的下一个字节地址。

  • 返回值:返回指向 dest 中值为 c 的下一个字节指针。返回值为 0 表示在 src 所指内存前 n 个字节中没有值为 c 的字节。

  • 相关函数:bcopy,memcpy,memmove,strcpy,strncpy

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char a[] = "string[a]";
    char b[] = "string(b)";
    char *c;
    c = memccpy(a, b, 'b', sizeof(b));
    printf("memccpy(): %s\n", a);
    if (c)
        printf("%s\n", c);
    return 0;
}

执行

memccpy(): string(b]
]

memchr

在某一内存范围中查找一特定字符

头文件

#include <string.h>

函数原型

void *memchr(const void *s, int c, size_t n);
  • 说明:memchr() 从头开始搜寻 s 所指的内存内容前 n 个字节,直到发现第一个值为 c 的字节,则返回指向该字节的指针。

  • 返回值:如果找到指定的字节则返回该字节的指针,否则返回 0。

  • 相关函数:index,rindex,strchr,strpbrk,strrchr,strsep,strspn,strstr

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *s = "0123456789012345678901234567890";
    char *p;
    p = memchr(s, '5', 10);
    printf("%s\n", p);
    return 0;
}

执行

56789012345678901234567890

memcmp

比较内存内容

头文件

#include <string.h>

函数原型

int memcmp(const void *s1, const void *s2, size_t n);
  • 说明:memcmp() 用来比较 s1 和 s2 所指的内存区间前 n 个字符。字符串大小的比较是以 ASCII 码表上的顺序来决定,此顺序亦为字符的值。memcmp() 首先将 s1 第一个字符值减去 s2 第一个字符的值,若差为 0 则再继续比较下个字符,若差值不为 0 则将差值返回。例如,字符串 “Ac” 和 “ba” 比较则会返回字符 ‘A’(65) 和 ‘b’(98) 的差值 (-33)。

  • 返回值:若参数 s1 和 s2 所指的内存内容都完全相同则返回 0 值。s1 若大于 s2 则返回大于 0 的值。s1 若小于 s2 则返回小于 0 的值。

  • 相关函数:bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *a = "aBcDeF";
    char *b = "AbCdEf";
    char *c = "aacdef";
    char *d = "aBcDeF";
    printf("memcmp(a,b): %d\n", memcmp((void*)a, (void*) b, 6));
    printf("memcmp(a,c): %d\n", memcmp((void*)a, (void*) c, 6));
    printf("memcmp(a,d): %d\n", memcmp((void*)a, (void*) d, 6));
    return 0;
}

执行

memcmp(a,b): 1    # 字符串a > 字符串b,返回 1
memcmp(a,c): -1   # 字符串a < 字符串c,返回 -1
memcmp(a,d): 0    # 字符串a = 字符串d,返回 0

memcpy

拷贝内存内容

头文件

#include <string.h>

函数原型

void *memcpy(void *dest, const void *src, size_t n);
  • 说明:memcpy() 用来拷贝 src 所指的内存内容前 n 个字节到 dest 所指的内存地址上。与 strcpy() 不同的是,memcpy() 会完整地复制 n 个字节,不会因为遇到字符串结束 ‘\0’ 而结束。

  • 返回值:返回指向 dest 的指针。

  • 附加说明:指针 src 和 dest 所指的内存区域不可重叠。

  • 相关函数:bcopy,memccpy,memcpy,memmove,strcpy,strncpy

示例

#include <stdio.h>
#include <string.h>

int main()
{
	char a[30] = "string (a)";
    char b[30] = "string\0string";
    int i;
    strcpy(a, b);
    printf("strcpy(): ");
    for(i=0; i<30; i++)
        printf("%c", a[i]);
    memcpy(a, b, 30);
    printf("\nmemcpy(): ");
    for(i=0; i<30; i++)
        printf("%c", a[i]);
    return 0;
}

执行

strcpy(): string(a)
memcpy(): stringstring

memmove

拷贝内存内容

头文件

#include <string.h>

函数原型

void *memmove(void *dest, const void *src, size_t n);
  • 说明:memmove() 和 memcpy() 一样都是用来拷贝 src 所指的内存内容前 n 个字节到 dest 所指的地址上。不同的是,当 src 和 dest 所指的内存区域重叠时,memmove() 仍然可以正确的处理,不过执行效率上会比使用 memcpy() 略慢些。

  • 返回值:返回指向 dest 的指针。

  • 附加说明:指针 src 和 dest 所指的内存区域可以重叠。

  • 相关函数:bcopy,memccpy,memcpy,strcpy,strncpy

示例

参考 memcpy()

memset

将一段内存空间填入某值

头文件

#include <string.h>

函数原型

void *memset(void *s, int c, size_t n);
  • 说明:memset() 会将参数 s 所指的内存区域前 n 个字节以参数 c 填入,然后返回指向 s 的指针。在编写程序时,若需要将某一数组作初始化,memset() 会相当方便。

  • 返回值:返回指向 s 的指针。

  • 附加说明:参数 c 虽声明为 int,但必须是 unsigned char,所以范围在 0 到 255 之间。

  • 相关函数:bzero,swab

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char s[30];
    memset(s, 'A', sizeof(s));
    s[30] = '\0';
    printf("%s\n", s);
    return 0;
}

执行

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

rindex

查找字符串中最后一个出现的指定字符

头文件

#include <string.h>

函数原型

char *rindex(const char *s, int c);
  • 说明:rindex() 用来找出参数 s 字符串中最后一个出现的参数 c 地址,然后将该字符出现的地址返回。字符串结束字符(NULL)也视为字符串一部分。

  • 返回值:如果找到指定的字符则返回该字符所在的地址,否则返回 0。

  • 相关函数:index,memchr,strchr,strrchr

示例

#include <string.h>
#include <string.h>

int main()
{
    char *s = "0123456789012345678901234567890";
    char *p;
    p = rindex(s, '5');
    printf("%s\n", p);
    return 0;
}

执行

567890

strcasecmp

忽略大小写比较字符串

头文件

#include <string.h>

函数原型

int strcasecmp(const char *s1, const char *s2);
  • 说明:strcasecmp() 用来比较参数 s1 和 s2 字符串,比较时会自动忽略大小写的差异。

  • 返回值:若参数 s1 和 s2 字符串相同则返回 0。s1 长度大于 s2 长度则返回大于 0 的值,s1 长度若小于 s2 长度则返回小于 0 的值。

  • 相关函数:bcmp,memcmp,strcmp,strcoll,strncmp

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *a = "aBcDeF";
    char *b = "AbCdEf";
    if(!strcasecmp(a, b))
        printf("%s=%s\n", a, b);
    return 0;
}

执行

aBcDeF=AbCdEf

strcat

连接两字符串

头文件

#include <string.h>

函数原型

char *strcat(char *dest, const char *src);
  • 说明:strcat() 会将参数 src 字符串拷贝到参数 dest 所指的字符串尾。第一个参数 dest 要有足够的空间来容纳要拷贝的字符串。

  • 返回值:返回参数 dest 的字符串起始地址。

  • 相关函数:bcopy,memccpy,memcpy,strcpy,strncpy

示例

#include <stdio.h.>
#include <string.h.>

int main()
{
    char a[30] = "string(1)";
    char b[] = "string(2)";
    printf("before strcat() : %s\n", a);
    printf(" after strcat() : %s\n", strcat(a, b));
    return 0;
}

执行

before strcat() : string(1)
 after strcat() : string(1)string(2)

strchr

查找字符串中第一个出现的指定字符

头文件

#include <string.h>

函数原型

char *strchr (const char *s, int c);
  • 说明:strchr() 用来找出参数 s 字符串中第一个出现的参数 c 地址,然后将该字符出现的地址返回。

  • 返回值:如果找到指定的字符则返回该字符所在地址,否则返回 0。

  • 相关函数:index,memchr,rinex,strbrk,strsep,strspn,strstr,strtok

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *s = "0123456789012345678901234567890";
    char *p;
    p = strchr(s, '5');
    printf("%s\n", p);
    return 0;
}

执行

56789012345678901234567890

strcmp

比较字符串

头文件

#include <string.h>

函数原型

int strcmp(const char *s1, const char *s2);
  • 说明:strcmp() 用来比较参数 s1 和 s2 字符串。字符串大小的比较是以 ASCII 码表上的顺序来决定,此顺序亦为字符的值。strcmp() 首先将 s1 第一个字符值减去 s2 第一个字符的值,若差为 0 则再继续比较下个字符,若差值不为 0 则将差值返回。例如,字符串 “Ac” 和 “ba” 比较则会返回字符 ‘A’(65) 和 ‘b’(98) 的差值 (-33)。

  • 返回值:若参数 s1 和 s2 字符串相同则返回 0,s1 若大于 s2 则返回大于 0 的值,s1 若小于 s2 则返回小于 0 的值。

  • 相关函数:bcmp,memcmp,strcasecmp,strncasecmp,strcoll

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *a = "aBcDeF";
    char *b = "AbCdEf";
    char *c = "aacdef";
    char *d = "aBcDeF";
    printf("strcmp(a,b) : %d\n", strcmp(a, b));
    printf("strcmp(a,c) : %d\n", strcmp(a, c));
    printf("strcmp(a,d) : %d\n", strcmp(a, d));
    return 0;
}

执行

strcmp(a,b) : 32
strcmp(a,c) : -31
strcmp(a,d) : 0

strcoll

采用目前区域的字符排列次序来比较字符串

头文件

#include <string.h>

函数原型

int strcoll(const char *s1, const char *s2);
  • 说明:strcoll() 会依环境变量 LC_COLLATE 所指定的文字排列次序来比较 s1 和 s2 字符串。

  • 返回值:若参数 s1 和 s2 字符串相同则返回 0,s1 若大于 s2 则返回大于 0 的值,s1 若小于 s2 则返回小于 0 的值。

  • 附加说明:若 LC_COLLATE 为 “POSIX” 或 “C”,则 strcoll() 与 strcmp() 作用完全相同。

  • 相关函数:strcmp,bcmp,memcmp,strcasecmp,strncasecmp

示例

参考 strcmp()

strcpy

拷贝字符串

头文件

#include <string.h>

函数原型

char *strcpy(char *dest, const char *src);
  • 说明:strcpy() 会将参数 src 字符串拷贝至参数 dest 所指的地址。

  • 返回值:返回参数 dest 的字符串起始地址。

  • 附加说明:如果参数 dest 所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用 strncpy() 来取代。

  • 相关函数:bcopy,memcpy,memccpy,memmove

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char a[30]="Hello, World!";
    char b[]="你好,世界!";
    printf("before strcpy() : %s\n", a);
    printf(" after strcpy() : %s\n", strcpy(a, b));
    return 0;
}

执行

before strcpy() : Hello, World!
 after strcpy() : 你好,世界!

strcspn

返回字符串中连续不含指定字符串内容的字符数

头文件

#include <string.h>

函数原型

size_t strcspn(const char *s, const char *reject);
  • 说明:strcspn() 从参数 s 字符串的开头计算连续的字符,而这些字符都完全不在参数 reject 所指的字符串中。简单地说,若 strcspn() 返回的数值为 n,则代表字符串 s 开头连续有 n 个字符都不含字符串 reject 内的字符。

  • 返回值:返回字符串 s 开头连续不含字符串 reject 内的字符数目。

  • 相关函数:strspn

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *str = "Linux was first developed for 386/486-based pcs.";
    printf("%d\n", strcspn(str, " "));
    printf("%d\n", strcspn(str, "/-"));
    printf("%d\n", strcspn(str, "1234567890"));
    return 0;
}

执行

5    # 值计算算到 " " 的出现,所以返回 "Linux" 的长度
33   # 计算到出现 "/" 或 "-",所以返回到 "6" 的长度
30   # 计算到出现数字字符为止,所以返回 "3" 出现前的长度

strdup

复制字符串

头文件

#include <string.h>

函数原型

char *strdup(const char *s);
  • 说明:strdup() 会先用 maolloc() 分配与参数 s 字符串相同的空间大小,然后将参数 s 字符串的内容复制到该内存地址,然后把该地址返回。该地址最后可以利用 free() 来释放。

  • 返回值:返回一字符串指针,该指针指向复制后的新字符串地址。若返回 NULL 表示内存不足。

  • 相关函数:calloc,malloc,realloc,free

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char a[]="strdup";
    char *b;
    b = strdup(a);
    printf("b[ ]=\"%s\"\n", b);
    return 0;
}

执行

b[ ]="strdup"

strlen

返回字符串长度

头文件

#include <string.h>

函数原型

size_t strlen (const char *s);
  • 说明:strlen() 用来计算指定的字符串 s 的长度,不包括结束字符 ‘\0’。

  • 返回值:返回字符串 s 的字符数。

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *str = "12345678";
    printf("str length = %d\n", strlen(str));
    return 0;
}

执行

str length = 8

strncasecmp

忽略大小写比较字符串

头文件

#include <string.h>

函数原型

int strncasecmp(const char *s1, const char *s2, size_t n);
  • 说明:strncasecmp() 用来比较参数 s1 和 s2 字符串前 n 个字符,比较时会自动忽略大小写的差异。

  • 返回值:若参数 s1 和 s2 字符串相同则返回 0,s1 若大于 s2 则返回大于 0 的值,s1 若小于 s2 则返回小于 0 的值。

  • 相关函数:bcmp,memcmp,strcmp,strcoll,strncmp

示例

#include <stdio.h>
#include<string.h>

int main()
{
    char *a = "aBcDeF";
    char *b = "AbCdEf";
    if(!strncasecmp(a, b))
        printf("%s=%s\n", a, b);
    return 0;
}

执行

aBcDef=AbCdEf

strncat

连接两字符串

头文件

#include <string.h>

函数原型

char *strncat(char *dest, const char *src, size_t n);
  • 说明:strncat() 会将参数 src 字符串拷贝 n 个字符到参数 dest 所指的字符串尾。第一个参数 dest 要有足够的空间来容纳要拷贝的字符串。

  • 返回值:返回参数 dest 的字符串起始地址。

  • 相关函数:bcopy,memccpy,memecpy,strcpy,strncpy

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char a[30] = "https://";
    char b[] = "getiot.tech";
    printf("before strnact() : %s\n", a);
    printf(" after strncat() : %s\n", strncat(a, b, strlen(b)+1));
    return 0;
}

执行

before strnact() : https://
 after strncat() : https://getiot.tech

strncpy

拷贝字符串

头文件

#include <string.h>

函数原型

char *strncpy(char *dest, const char *src, size_t n);
  • 说明:strncpy() 会将参数 src 字符串拷贝前 n 个字符至参数 dest 所指的地址。

  • 返回值:返回参数 dest 的字符串起始地址。

  • 相关函数:bcopy,memccpy,memcpy,memmove

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char a[30]="Hello, World!";
    char b[]="你好,世界!";
    printf("before strncpy() : %s\n", a);
    printf(" after strncpy() : %s\n", strncpy(a, b, strlen(b)+1));
    /* 注意给'\0'留位置 */
    /* 否则可能出现 warning: ‘strncpy’ output truncated before terminating nul copying */
    return 0;
}

执行

before strncpy() : Hello, World!
 after strncpy() : 你好,世界!

strpbrk

查找字符串中第一个出现的指定字符

头文件

#include <string.h>

函数原型

char *strpbrk(const char *s, const char *accept);
  • 说明:strpbrk() 用来找出参数 s 字符串中最先出现存在参数 accept 字符串中的任意字符。

  • 返回值:如果找到指定的字符则返回该字符所在地址,否则返回 0。

  • 相关函数:index,memchr,rindex,strpbrk,strsep,strspn,strstr,strtok

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *s = "0123456789012345678901234567890";
    char *p;
    p = strpbrk(s, "a1 839"); /* 1会最先在s字符串中找到 */
    printf("%s\n", p);
    p = strpbrk(s, "4398");    /* 3会最先在s字符串中找到*/
    printf("%s\n", p);
    return 0;
}

执行

123456789012345678901234567890
3456789012345678901234567890

strrchr

查找字符串中最后出现的指定字符

头文件

#include <string.h>

函数原型

char *strrchr(const char *s, int c);
  • 说明:strrchr() 用来找出参数 s 字符串中最后一个出现的参数 c 地址,然后将该字符出现的地址返回。

  • 返回值:如果找到指定的字符则返回该字符所在地址,否则返回 0。

  • 相关函数:index,memchr,rindex,strpbrk,strsep,strspn,strstr,strtok

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char *s = "0123456789012345678901234567890";
    char *p;
    p = strrchr(s, '5');
    printf("%s\n", p);
    return 0;
}

执行

567890

strspn

返回字符串中连续不含指定字符串内容的字符数

头文件

#include <string.h>

函数原型

size_t strspn(const char *s, const char *accept);
  • 说明:strspn() 从参数 s 字符串的开头计算连续的字符,而这些字符都完全是 accept 所指字符串中的字符。简单来说,若 strspn() 返回的数值为 n,则代表字符串 s 开头连续有 n 个字符都是属于字符串 accept 内的字符。

  • 返回值:返回字符串 s 开头连续包含字符串 accept 内的字符数目。

  • 相关函数:strcspn,strchr,strpbrk,strsep,strstr

示例

#include <stdio.h>
#include<string.h>

int main()
{
    char *str = "Linux was first developed for 386/486-based PCs.";
    char *t1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    printf("%d\n", strspn(str, t1));
    return 0;
}

执行

5    # 计算大小写字母。不包含 " ",所以返回 Linux 的长度

strstr

在一字符串中查找指定的字符串

头文件

#include <string.h>

函数原型

char *strstr(const char *haystack, const char *needle);
  • 说明:strstr() 会从字符串 haystack 中搜寻字符串 needle,并将第一次出现的地址返回。

  • 返回值:返回指定字符串第一次出现的地址,否则返回 0。

  • 相关函数:index,memchr,rindex,strchr,strpbrk,strsep,strspn,strtok

示例

#include <stdio.h>
#include<string.h>

int main()
{
    char * s = "012345678901234567890123456789";
    char *p;
    p = strstr(s, "901");
    printf("%s\n", p);
    return 0;
}

执行

901234567890123456789

strtok

分隔字符串

头文件

#include <string.h>

函数原型

char *strtok(char *s, const char *delim);
  • 说明:strtok() 用来将字符串分割成一个个片段。参数 s 指向欲分割的字符串,参数 delim 则为分割字符串,当 strtok() 在参数 s 的字符串中发现到参数 delim 的分割字符时则会将该字符改为 ‘\0’ 字符。在第一次调用时,strtok() 必需给予参数 s 字符串,往后的调用则将参数 s 设置成 NULL。每次调用成功则返回下一个分割后的字符串指针。

  • 返回值:返回下一个分割后的字符串指针,如果已无从分割则返回 NULL。

  • 相关函数:index,memchr,rindex,strpbrk,strsep,strspn,strstr

示例

#include <stdio.h>
#include <string.h>

int main()
{
    char s[] = "ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z";
    char *delim = "-: ";
    char *p;

    printf("%s\n", s);
    printf("%s ", strtok(s, delim));
    while((p = strtok(NULL, delim)))
        printf("%s\n", p);

    return 0;
}

执行

ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z
# '-' 和 ':' 字符已经被 '\0' 字符取代
ab cd
ef;gh
i
jkl;mnop;qrs
tu
vwx
y;z