首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >收集飞花令碎片——C语言字符串(纯干货)

收集飞花令碎片——C语言字符串(纯干货)

作者头像
枫亭湖区
发布2025-11-13 09:05:39
发布2025-11-13 09:05:39
60
举报
C语言的字符串大串讲

前言

在走进的代码世界之前,先领略一下小桥流水美景的诗意世界吧

完了就直接进入正题

一、C语言字符串的手动内存管理

1、C语言无字符串

代码语言:javascript
复制
"hello bit.\n"

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串 注:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。

2、'\0’的重要性

代码语言:javascript
复制
#include <stdio.h>
//下面代码,打印结果是什么?为什么?(突出'\0'的重要性)
int main()
{
    char arr1[] = "Hello";
    char arr2[] = { 'H', 'e', 'l', 'l', 'o' };
    char arr3[] = { 'H', 'e', 'l', 'l', 'o', '\0'};
    printf("%s\n", arr1);
    printf("%s\n", arr2);
    printf("%s\n", arr3);
    return 0;
}
在这里插入图片描述
在这里插入图片描述

在上面的代码运行结果可以看到,我们在输出arr2时出现了乱码形式

思考:为什么会出现这种情况呢? 因为在arr2中并不包含字符串的结束标志即’\0’,所以会出现上面的乱码!

字符串与\0的深度解析
  1. 当我们用printf()函数以字符串形式进行输出时,只有遇到’\0’才会停止输出 这时候肯定会有码友会问:为什么输出arr1就不会产生乱码?
  2. 因为在 “” 里面的字符串中就已经自动包含了字符串的结束标志即’\0’,所以当我们输出arr1自然就不会产生乱码
  3. 当我们在使用 {} 字符串的定义的方式时,一定要记得加上字符串的结束标志,否则就会出现乱码现象

小编提醒:一个合格的程序员必备的素养,是对代码的每一处细节严格把控,虽然我们有时候用不到,但这却是我们必须要做的

3、字符串的初始化

方式

示例

说明

直接赋值

char s[] = "abc";

自动计算长度并补 '\0'(长度=4)

指定大小

char s[5] = "abc";

剩余空间填充 '\0'(实际存储 a b c \0 \0)

逐个字符

char s[4] = {'a','b','c','\0'};

必须显式添加 '\0',否则不是合法字符串

指针

char *s = "abc";

指向只读的字符串常量(不可修改内容)

4、与字符串相关的格式说明符

在 C 语言中,与字符串相关的格式说明符主要用于输入/输出函数

(1)%s

用途:输入/输出 字符串(以 ‘\0’ 结尾的 char 数组或指针)。

代码示例:

代码语言:javascript
复制
char str[] = "Hello";
printf("%s\n", str);  // 输出字符串
scanf("%s", str);     // 输入字符串(遇空格停止)
  • 注意: scanf(“%s”, str) 不安全(可能缓冲区溢出),推荐:
代码语言:javascript
复制
scanf("%19s", str);  // 限制最大长度(数组大小-1)
  • 或使用 fgets:
代码语言:javascript
复制
fgets(str, sizeof(str), stdin);  // 更安全(读取一行)
(2)%c

用途:输入/输出 单个字符(char 类型)。

代码示例:

代码语言:javascript
复制
char ch = 'A';
printf("%c\n", ch);  // 输出字符 'A'
scanf("%c", &ch);    // 输入单个字符(包括空格/换行)

注意:

若需跳过空白字符,加空格:

代码语言:javascript
复制
scanf(" %c", &ch);  // 忽略前面的空格/换行
(3)%p

用途:输出 指针的地址(十六进制格式)。

代码示例:

代码语言:javascript
复制
char *ptr = "Hello";
printf("%p\n", (void *)ptr);  // 输出指针地址(如 0x55a1b2c3d4e5)

后面我们讲到指针的时候会深度解析

拓展:fgets

fgets 是 C 语言标准库中用于安全读取字符串的重要函数,相比 gets 和 scanf 的 %s,它提供了更好的安全性和控制能力。

最简单的 fgets 使用模板
代码语言:javascript
复制
#include <stdio.h>

int main() {
    char buffer[100]; // 定义一个足够大的字符数组
    
    printf("请输入内容: ");
    fgets(buffer, sizeof(buffer), stdin); // 读取输入
    
    printf("你输入的是: %s", buffer);
    
    return 0;
}z
关键要点

三个必要参数: buffer:存储输入的字符数组 sizeof(buffer):最大读取长度(自动计算数组大小) stdin:表示从标准输入(键盘)读取

自动添加结束符: fgets 会自动在字符串末尾添加 \0 所以实际读取的字符数 = 指定长度 - 1

拓展:使用fgets的时候,如何去掉换行符

如果用户按了回车,换行符 \n 会被包含在字符串中 示例:输入 “hello” 后按回车,buffer 内容为 “hello\n\0” 这时候我们可以用到头文件<string.h>来去除换行符 头文件<string.h>的讲解篇章在下面

代码语言:javascript
复制
#include <stdio.h>
#include <string.h> // 需要用到 strcspn

int main() {
    char buffer[100];
    
    printf("请输入: ");
    fgets(buffer, sizeof(buffer), stdin);
    
    // 去除换行符
    buffer[strcspn(buffer, "\n")] = '\0';
    
    printf("处理后的输入: %s", buffer);
    return 0;
}
(4)其它相关的格式说明符

下面这些说明符虽然功能强大,但是很少被使用,这里我们只是作简单的讲解,感兴趣的朋友可以去了解一下

1. %[…](扫描集)

用途:自定义 scanf 的输入规则。

  • 代码示例:
代码语言:javascript
复制
char str[50];
scanf("%[^\n]", str);  // 读取一行(直到换行符)
scanf("%[a-z]", str);  // 只读取小写字母
  • 常见用法:

%[^\n]:读取一行(含空格)。 %[^,]:读取直到逗号。

2. %n

用途:记录已输出的字符数(不消耗参数)。

  • 代码示例:
代码语言:javascript
复制
int count;
printf("Hello%nWorld\n", &count);  // count = 5("Hello"的长度)
3. %*s(抑制赋值)

用途:跳过输入的字符串。

  • 代码示例:
代码语言:javascript
复制
char str[10];
scanf("%*s %s", str);  // 跳过第一个单词,读取第二个

二、C语言字符串的库函数

<string.h> 是C语言中处理字符串和内存操作的重要头文件,下面介绍其中最常用的函数,适合初学者掌握核心功能。 由于<string.h>包含很多英文,为了方便大家的记忆,我会将每个英文前置并在后面附上其作用,方便大家的记忆

1、字符串基本操作

(1) strlen(长度计算)
代码语言:javascript
复制
size_t len = strlen(str); // 不计算'\0'
(2) strcpy(复制)
代码语言:javascript
复制
strcpy(char dest[] , const char arc[]);  // 可能溢出
  • 功能:将src字符串复制到dest字符串
(2.1)strncpy(复制):
代码语言:javascript
复制
strncpy(dest, src, n); // 最多复制n个字符
  • 功能:strncpy可以指定最大复制字符数
(3) strcat(连接)
代码语言:javascript
复制
strcat(dest, src); // 可能溢出
(3.1)strncat(连接)
代码语言:javascript
复制
strncat(dest, src, n); // 最多连接n个字符
(4) strcmp(比较)
代码语言:javascript
复制
int strcmp(const char str1[], const char str2[]);
  • 功能:比较两个字符串
(4.1)strncmp(比较)
代码语言:javascript
复制
int strncmp(const char str1[], const char str2[], size_t n);
  • 功能:指定几个字符进行比较

返回值:

  • 0:相等
  • 负数:str1小于str2
  • 正数:str1大于str2

代码示例:

代码语言:javascript
复制
if(strcmp("apple", "banana") < 0) {
    printf("apple在banana前面");
}

2、内存操作函数

(1)memset(内存设置)
代码语言:javascript
复制
void memset(char arr[], int value, size_t num);
  • 功能:将arr数组的前num个字节设置为value,常用于初始化数组

代码示例:

代码语言:javascript
复制
char buffer[50];
memset(buffer, 0, 50); // 将buffer全部初始化为0
(2)memcpy(内存复制)
代码语言:javascript
复制
void memcpy(char dest[], const char src[], size_t num);
  • 功能:从src数组复制num个字节到dest数组

代码示例:

代码语言:javascript
复制
int src[5] = {1,2,3,4,5};
int dest[5];
memcpy(dest, src, sizeof(src)); // 复制整个数组

3、内存查找函数

(1) strchr(查找字符位置)
代码语言:javascript
复制
int strchr(const char str[], int c);
  • 功能:查找字符c在str中第一次出现的位置,返回字符的索引位置,找不到返回-1

代码示例:

代码语言:javascript
复制
int pos = strchr("Hello", 'l'); // pos现在是2
(2) strstr(查找子串位置)
代码语言:javascript
复制
int strstr(const char haystack[], const char needle[]);
  • 功能:在haystack中查找needle,返回子串开始的位置索引,找不到返回-1

代码示例:

代码语言:javascript
复制
int pos = strstr("Hello world", "wor"); // pos现在是6

注意事项 使用这些函数时要确保目标数组足够大 字符串必须以’\0’结尾 数组索引从0开始计算 记得包含头文件 #include <string.h>

三、小编附言

为了方便大家的理解,本期的字符串没有附带指针的内容,后续讲指针的时候,会与字符串联系在一起讲

看到这里麻烦给个三连吧

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C语言的字符串大串讲
  • 前言
  • 一、C语言字符串的手动内存管理
    • 1、C语言无字符串
    • 2、'\0’的重要性
      • 字符串与\0的深度解析
    • 3、字符串的初始化
    • 4、与字符串相关的格式说明符
      • (1)%s
      • (2)%c
      • (3)%p
      • (4)其它相关的格式说明符
  • 二、C语言字符串的库函数
    • 1、字符串基本操作
      • (1) strlen(长度计算)
      • (2) strcpy(复制)
      • (3) strcat(连接)
      • (4) strcmp(比较)
    • 2、内存操作函数
      • (1)memset(内存设置)
      • (2)memcpy(内存复制)
    • 3、内存查找函数
      • (1) strchr(查找字符位置)
      • (2) strstr(查找子串位置)
  • 三、小编附言
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档