C 语言书
模块二 · 流程与数据 / 第 11 课

11 · 字符串基础

核心 35 分钟 跳到过关题
学习目标
  • 知道字符串以 \0 结尾
  • 会用 strlen / strcpy 等基础函数
  • 会安全地读入简单字符串

字符串是什么

C 里字符串是 char 数组 + 结尾的空字符 \0。

"hi" 实际是 {'h','i','\0'},占 3 字节。

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

int main(void)
{
    char name[20] = "Ada";
    printf("%s\n", name);
    printf("长度 = %lu\n", (unsigned long)strlen(name)); /* 3,不算 \0 */
    return 0;
}

常用函数

函数作用头文件
strlen(s)长度(不含 \0)string.h
strcpy(dst, src)把 src 拷到 dststring.h
strcmp(a,b)比较,0 表示相等string.h
printf("%s", s)打印字符串stdio.h
dst 必须够大
strcpy 不会帮你检查空间。dst 太小会写越界,是经典漏洞来源。
#include <stdio.h>
#include <string.h>

int main(void)
{
    char a[20] = "hello";
    char b[20];

    strcpy(b, a);
    printf("%s\n", b);

    if (strcmp(a, b) == 0)
    {
        printf("相同\n");
    }
    return 0;
}

和字符的区别

  • 'a':char,一个字符
  • "a":字符串,至少 {'a','\0'}
  • 数组长度要为结尾 \0 留位置:要存 5 个可见字符,至少 char s[6]

读入字符串

#include <stdio.h>

int main(void)
{
    char name[32];

    printf("你的名字: ");
    scanf("%31s", name);   /* 最多读 31 个,给 \0 留位置 */
    printf("你好, %s\n", name);
    return 0;
}

逐个字符处理

很多题目要把字符串当字符数组遍历,遇到 \0 停:

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

int main(void)
{
    char s[32] = "Hello";
    int i;

    for (i = 0; s[i] != '\0'; i++)
    {
        printf("%c ", s[i]);
    }
    printf("\n长度=%zu\n", strlen(s));
    return 0;
}

strcat 连接

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

int main(void)
{
    char buf[64] = "Hello";
    strcat(buf, ", ");      /* buf 变成 "Hello, " */
    strcat(buf, "World");   /* "Hello, World" */
    printf("%s\n", buf);
    return 0;
}

本课过关

必做

strlen("abc") 的值是?

必做作业
  1. 定义能存 10 个字符的数组,初始化为 "Hi"。
  2. 用 strcmp 判断两个字符串是否相等。
  3. 为什么 char s[3] = "abc" 可能有问题?
  4. 写程序:读入一个单词,统计它有几个字符。
先自己写完,再点开看解答

1:char s[10] = "Hi"; 后面自动补 \0,剩余字节为 0。

2:比较是否相等

char a[20] = "hello";
char b[20] = "hello";
if (strcmp(a, b) == 0)
    printf("相同\n");
else
    printf("不同\n");

3:char s[3]="abc":字面量需要 a,b,c,\0 共 4 字节,s[3] 只有 3 字节,装不下结尾 \0。之后 strlen 可能越界乱读。至少写 char s[4]。

4:统计单词长度

char w[64];
scanf("%63s", w);
printf("长度=%zu\n", strlen(w));