C/C++中的字符串

news/2025/2/24 5:55:10
  1. 字符串表示方式

    • 在C语言中,字符串实际上是一个字符数组(字节数组),并且以空字符 \0 结尾。例如,字符串 "RUNOOB" 实际上在内存中表示为 {'R', 'U', 'N', 'O', 'O', 'B', '\0'}
    • 这个 \0 终止符告诉标准库函数(如 printf()strlen() 等)字符串在哪里结束。
  2. 防止未定义行为

    • 如果没有正确地添加 \0 终止符,使用这些标准库函数时可能会导致未定义行为。例如,printf("%s", str) 会继续读取内存直到找到一个 \0,这可能导致读取到不相关的内存区域,甚至引发程序崩溃或安全漏洞(如缓冲区溢出攻击)。

1. 使用示例1

假设你有一个长度为5的字符串 "hello",你需要至少6个字节的空间来存储它(包括 \0 终止符)。

char str[6] = "hello";  // 正确,隐式包含 \0
// 或者
char str[] = "hello";   // 正确,编译器自动计算大小并包含 \0

如果只分配了5个字节:

char str[5] = "hello";  // 错误,没有空间留给 \0

在这种情况下,str 不会被正确地视为一个C字符串,因为缺少终止符 \0

2. 使用示例2

2.1 错误示例1

char buffer[5];
sprintf(buffer, "hello");  // 错误,buffer 只有 5 字节,不足以容纳 "hello\0"

2.2 错误示例2

char buffer[7];
int num = 4;
sprintf(buffer, "hello %d", num);  // 错误,buffer 只有7字节,不足以容纳 "hello 5\0"

2.3 正确示例

/* 恰巧开辟缓冲区 */

char buffer[8];
int num = 4;
sprintf(buffer, "hello %d", num);  // 错误,buffer 只有7字节,不足以容纳 "hello 5\0"



/* 开辟稍微大一点的缓冲区 */
char buffer[256];
int num = 4;
sprintf(buffer, "hello %d", num);  // 错误,buffer 只有7字节,不足以容纳 "hello 5\0"

3. char *str和char str2[]的用法

3.1 char *str的使用场景

函数参数传递:当需要将字符串传递给函数时,通常使用指针,因为指针只需要传递地址,效率较高。

void printString(const char *str) {
    printf("%s\n", str);
}

结构体中使用字符串:

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

// 定义一个包含字符指针的结构体
struct Person {
    char *name;  // 指向字符串的指针
    int age;
};

int main() {
    // 动态分配内存并初始化结构体实例
    struct Person person1;
    person1.name = (char *)malloc(50 * sizeof(char));  // 分配50字节的内存
    if (person1.name == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }
    strcpy(person1.name, "Alice");
    person1.age = 30;

    // 打印结构体内容
    printf("Name: %s\n", person1.name);
    printf("Age: %d\n", person1.age);

    // 修改结构体中的字符串
    strcpy(person1.name, "Bob");

    // 再次打印结构体内容
    printf("Name: %s\n", person1.name);
    printf("Age: %d\n", person1.age);

    // 释放分配的内存
    free(person1.name);

    return 0;
}

3.2 char str2[]的使用场景

固定大小的字符串:当你知道字符串的最大长度并且不需要动态调整大小时,使用字符数组更为合适。

char buffer[100];
fgets(buffer, sizeof(buffer), stdin);  // 从标准输入读取最多99个字符

结构体中使用字符串:

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

// 定义一个包含字符数组的结构体
struct Person {
    char name[50];  // 假设名字的最大长度为49个字符(包括终止符)
    int age;
};

int main() {
    // 创建并初始化结构体实例
    struct Person person1 = {"Alice", 30};
    
    // 修改结构体中的字符串
    strcpy(person1.name, "Bob");

    // 打印结构体内容
    printf("Name: %s\n", person1.name);
    printf("Age: %d\n", person1.age);

    return 0;
}

总结:当能大致估计字符串的长度时,直接使用字符数组;当我估计不到字符串有多长时,直接使用字符指针;


http://www.niftyadmin.cn/n/5864004.html

相关文章

[AI]【Comfyui】 生成基本流程图的步骤保姆记录

在进行深度学习模型或图像生成的过程中,创建流程图能够帮助清晰地表达模型的工作流程和数据流动。本文将为您介绍生成基本流程图的一般步骤,适用于常见的深度学习图像生成模型。以下是该流程图的基本步骤: 1. 创建 Load Checkpoint 节点 流程图的第一步通常是加载已经训练好…

网页制作07-html,css,javascript初认识のhtml添加多媒体

在网页中&#xff0c;&#xff0c;除了可以添加文本和图像之外还可以插入动画声音视频等媒体元素&#xff0c;如滚动效果、 Flash、 Active x以及midi声音文件等 一、设置滚动效果 1、滚动标记marquee 1)简介:使用marquee标记不仅可以滚动文字&#xff0c;也可以移动图片表格…

2025雅森北京展今天开幕,全景展现新能源汽车时代

推动汽车后市场全产业链向新向优转型升级 在2月21日举行的第36届中国国际汽车服务用品及设备展览会&#xff0c;中国国际新能源汽车技术、零部件及服务展览会&#xff08;雅森北京展CIAACE&#xff09;上&#xff0c;雅森国际总裁谢宇表示&#xff0c;当前正处在汽车行业新旧动…

鸿蒙5.0实战案例:基于ArkUI的验证码实现

往期推文全新看点&#xff08;文中附带全新鸿蒙5.0全栈学习笔录&#xff09; ✏️ 鸿蒙&#xff08;HarmonyOS&#xff09;北向开发知识点记录~ ✏️ 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…

使用Adobe Premiere Pro 2024软件实现多图片水平划出切换

使用Adobe Premiere Pro 2024软件实现多图片水平划出切换 步骤总结 纯PR新手操作&#xff0c;有误见谅。目标&#xff1a;试图使用PR2024实现图片间的水平滑入滑出切换&#xff0c;以对比相同内容不同图片之间的质量。实现效果&#xff1a;例如&#xff0c;有AB两图像&#xff…

【JavaEE进阶】Spring DI

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗 如有错误&#xff0c;欢迎指出~ 依赖注⼊是⼀个过程&#xff0c;是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源&#xff0c;⽽资源指的就是对象. 在上⾯程序案例中&#xff0c;我们使⽤了 Autowired 这…

libwebsockets交叉编译全流程

libwebsocket中的webscoket加密功能需要依赖于Openssl库因此需要提前准备好openssl开源库。 交叉编译openssl 下面演示源码方式交叉编译OpenSSL为动态库。 创建个Websocket文件夹&#xff0c;把后续的成果物均放在这个文件中&#xff0c;文件夹中创建子文件夹OpenSSL和libWeb…

TIKTOK矩阵系统的软件服务

TikTok矩阵系统的技术服务概述 随着TikTok平台的发展&#xff0c;越来越多的内容创作者和企业选择通过矩阵系统来优化他们的内容管理和推广。TikTok矩阵系统是一种旨在高效管理多个账户、提升内容曝光、增强互动和加速推广的技术工具。以下是该系统提供的主要功能和技术服务&a…