3. 字符串运算

字符串主要用于存储文字信息。字符串对应的操作也是文字相关的操作,主要有求长度复制拼接比较查找等。字符串的运算我们可以自己编写算法来完成。一般最快捷的方式使用 C 语言的标准库函数进行操作。

字符串常用的运算和对应的函数如下:

  1. 求长度:strlen。
  2. 复制:strcpy、strncpy。
  3. 拼接:strcat、strncat。
  4. 比较大小:strcmp、strncmp。
  5. 字符串查找:strstr。

如下列出了字符串运算常用的函数和对应的说明。

函数
说明
size_t strlen(const char *s);
计算字符串的长度并返回这个长度(不包含尾零 '\0'
char *strcpy(char *dst, const char *src);
src 开始的字节复制到 dst 位置(包含 src 的尾零 '\0'),返回 dst
char *strncpy(char *dst, const char *src, size_t n);
src 开始的最多 n 个字节复制到 dst 位置,返回 dst,如果 strlen(src) < n 则包含尾零 '\0',否则不复制尾零。
char *strcat(char *dst, const char *src);
src 开始的字符串复制到 dst 字符串尾零 '\0'开始的位置实现拼接,dst 末尾添加尾零 '\0'并返回 dst
char *strncat(char *dst, const char *src, size_t n);
src 开始的最多 n 个字节复制到 dst 字符串尾零 '\0'开始的位置实现拼接,dst 末尾添加尾零 '\0'并返回 dst
int strcmp(const char *s1, const char *s2);
比较字符串 s1s2 的大小,相等返回 0,s1 小于 s2 返回负值, s1 大于 s2 返回正值。
int strncmp(const char *s1, const char *s2, size_t n);
比较字符串前n个字符 s1s2 的大小,相等返回 0,s1 小于 s2 返回负值, s1 大于 s2 返回正值。
char *strstr(const char *haystack, const char *needle);
在 字符串 haystack 中查找 needle 是否存在,如果存在返回 needle 第一个字符在haystack 中的位置。失败返回 NULL

以上这些函数都声明在 string.h 头文件中。

以下将以示例形式详细讲解上述函数。

1、求长度:strlen

示例:

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

int main(int argc, char *argv[]) {
    char s1[100] = "ABC";  // 长度不包含尾零'\0'

    printf("strlen(s1): %ld\n", strlen(s1));
    printf("hello's length: %ld\n", strlen("hello"));
    return 0;
}

运行结果如下:

strlen(s1): 3
hello's length: 5

2、复制:strcpy、strncpy。

示例:

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

int main(int argc, char *argv[]) {
    char s1[7] = "ABCDEF";

    strcpy(s1, "123");
    printf("s1: %s\n", s1);

    strncpy(s1, "abcdefg", 4);
    printf("s1: %s\n", s1);

    return 0;
}

运行结果如下:

s1: 123
s1: abcdEF

上述运行结果内存结构示意图。

// char s1[7] = "ABCDEF";
    +-----+-----+-----+-----+-----+-----+-----+----
s1  | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | '\0'| ...
    +-----+-----+-----+-----+-----+-----+-----+----

// 执行 strcpy(s1, "123"); 后
    +-----+-----+-----+-----+-----+-----+-----+----
s1  | '1' | '2' | '3' | '\0'| 'E' | 'F' | '\0'| ...
    +-----+-----+-----+-----+-----+-----+-----+----

// 执行 strncpy(s1, "abcdefg", 4);  后
    +-----+-----+-----+-----+-----+-----+-----+----
s1  | 'a' | 'b' | 'c' | 'd' | 'E' | 'F' | '\0'| ...
    +-----+-----+-----+-----+-----+-----+-----+----

3、拼接:strcat、strncat

示例:

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

int main(int argc, char *argv[]) {
    char s1[9] = "AB";

    strcat(s1, "CD");
    printf("s1: %s\n", s1);

    strncat(s1, "EF", 8);
    printf("s1: %s\n", s1);

    strncat(s1, "GHIJK", 2);
    printf("s1: %s\n", s1);

    return 0;
}

运行结果如下:

s1: ABCD
s1: ABCDEF
s1: ABCDEFGH

上述运行结果内存结构示意图。

// char s1[9] = "AB";
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----
s1  | 'A' | 'B' | '\0'| '\0'| '\0'| '\0'| '\0'| '\0'| '\0'| ...
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----

// 执行 strcat(s1, "CD"); 后
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----
s1  | 'A' | 'B' | 'C' | 'D' | '\0'| '\0'| '\0'| '\0'| '\0'| ...
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----

// 执行 strncat(s1, "EF", 8); 后
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----
s1  | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | '\0'| '\0'| '\0'| ...
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----

// 执行 strncat(s1, "GHIJK", 2); 后
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----
s1  | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | '\0'| ...
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+----

4、比较大小:strcmp、strncmp

字符串比较是两个字符串的第一个字符的值先比较,如果相同才会比较下一个,否则直接返回结果。

示例:

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

int main(int argc, char *argv[]) {
    char s1[] = "1234";
    char s2[] = "125";

    printf("strcmp(s1, s2): %d\n", strcmp(s1, s2));
    printf("strcmp(s1, s2): %d\n", strncmp(s1, s2, 2));

    printf("strcmp(\"abc\", \"acb\"): %d\n", strcmp("abc", "acb"));
    printf("strcmp(\"23\", \"123\"): %d\n", strcmp("23", "123"));

    return 0;
}

运行结果如下:

strcmp(s1, s2): -2
strcmp(s1, s2): 0
strcmp("abc", "acb": -1
strcmp("23", "123": 1

5、字符串查找:strstr

示例:

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

int main(int argc, char *argv[]) {
    char s1[100] = "hello world!";
    char * p_ret = NULL;

    p_ret = strstr(s1, "world");
    if (p_ret) {
        // 指针相减获取指针间间隔的元素个数。
        printf("找到了\"world\", 它在 s1 的:%ld 位置\n", p_ret - s1);
    } else {
        printf("没有找到\"world\"\n");
    }

    p_ret = strstr(s1, "laowei");
    printf("p_ret:%p\n", p_ret);

    return 0;
}

运行结果如下:

找到了"world", 它在 s1 的:6 位置
p_ret:(nil)

练习: