深入了解c语言字符串 2

深入了解c语言字符串 2

    • 一 使用 scanf进行字符串的输入:
      • 1.1输入单词(不包含空格):
      • 1.2 输入带空格的整行文本:
      • 1.3 处理输入缓冲区:
      • 1.4 注意安全性:
    • 二 使用 printf 字符串的输出:
    • 三 输入输出中的一些常见问题和注意事项
      • 3.1. 缓冲区溢出:
      • 3.2 空白字符的处理:
      • 3.3 字符串结束标志:
      • 3.4 字符串长度的处理:
      • 3.5格式化字符串的处理:
      • 3.6 动态内存分配:

前言

Hello 大家好!我是甜美的江。

在这里插入图片描述
本博客将详细介绍C语言字符串的输入输出,深入探讨如何安全地处理用户输入,避免常见问题如缓冲区溢出、空白字符处理不当以及字符串结束标志等引发的潜在风险。

一 使用 scanf进行字符串的输入:

在C语言中,scanf(点击有惊喜哦) 函数用于从标准输入(通常是键盘)读取输入数据。如果你想使用 scanf 来输入字符串,有几种方式可以考虑,但需要注意字符串输入的一些特殊情况。以下是关于使用 scanf 进行字符串输入的详细介绍:

1.1输入单词(不包含空格):

代码:

#include <stdio.h>

int main() {
    char word[20];  // 假设输入的单词最多包含19个字符

    printf("Enter a word: ");
    scanf("%19s", word);

    printf("You entered: %s\n", word);
    return 0;
}

运行结果:

Enter a word: abcdefghijk
You entered: abcdefghijk

在上面的例子中,%s 是格式指示符,它用于读取一个字符串,但默认情况下,scanf 在遇到空格、制表符或换行符时就停止读取。
如:

Enter a word: abcd efh
You entered: abcd

碰到空格,scanf 停止读取,只读取到abcd。

另外,为了避免溢出缓冲区,使用 %19s 来指定最多读取19个字符,留一个字符给字符串结尾的空字符\0。

1.2 输入带空格的整行文本:

如果需要输入包含空格的整行文本,可以使用 %[ 这种方式:

代码:

#include <stdio.h>

int main() {
    char line[50];  // 假设输入的文本最多包含49个字符

    printf("Enter a line: ");
    scanf(" %[^\n]", line);

    printf("You entered: %s\n", line);
    return 0;
}

运行结果:

Enter a line: abcd efgh
You entered: abcd efgh

可以看到结果中,scanf成功读取了空格。

%[^\n] 表示读取除了换行符 \n 以外的所有字符,这样可以读取整行文本。

1.3 处理输入缓冲区:

在使用 scanf 读取字符串时,可能会遇到输入缓冲区的问题,尤其是当在之前使用了其他输入函数时。为了清除输入缓冲区的残留内容,可以使用 getchar 函数:

#include <stdio.h>

int main() {
    char word[20];

    // 清除输入缓冲区
    while (getchar() != '\n');

    printf("Enter a word: ");
    scanf("%19s", word);

    printf("You entered: %s\n", word);
    return 0;
}

这个例子中的 while (getchar() != ‘\n’); 用于清除输入缓冲区中的所有字符,直到遇到换行符为止。

1.4 注意安全性:

在使用 scanf 时,需要小心处理输入,避免溢出缓冲区的情况,确保为数组分配足够的空间。可以使用 fgets 函数来更安全地处理输入,特别是当涉及到字符串输入时。

总体而言,使用 scanf 进行字符串输入需要谨慎处理,避免缓冲区溢出和其他输入问题。

二 使用 printf 字符串的输出:

在C语言中,使用 printf 函数进行字符串的输出是一种常见的操作。printf 函数是C标准库中的一个输出函数,它根据指定的格式将数据输出到标准输出设备(通常是终端窗口)。

代码:

#include <stdio.h>

int main() {
    char str[] = "Hello, World!";
    printf("String: %s\n", str);
    return 0;
}

运行结果:

String: Hello, World!

在上面的例子中,%s 是格式控制字符串中的格式指示符,用于指示要输出的是字符串。str 是一个包含字符串的字符数组。

三 输入输出中的一些常见问题和注意事项

在C语言中,字符串输入输出涉及到一些常见的问题和需要注意的事项。下面是一些常见问题和相应的注意事项:

3.1. 缓冲区溢出:

问题:

当使用 scanf 或 gets 时,如果输入的字符串长度超过了目标缓冲区的大小,会导致缓冲区溢出,可能破坏程序的内存结构。

注意事项:

使用 fgets 替代 gets,因为 fgets 允许指定最大读取字符数,有助于避免缓冲区溢出。
在使用 scanf 时,最好指定字符串的最大长度,并使用 %s 格式说明符,如 scanf(“%19s”, str)。

代码示例及分析:

#include <stdio.h>

int main() {
    char str[10]; // 仅能容纳9个字符 + '\0'

    printf("Enter a string: ");
    scanf("%s", str); // 可能导致缓冲区溢出

    printf("You entered: %s\n", str);

    return 0;
}

在这个示例中,缓冲区 str 的大小为10,但是用户可以输入超过10个字符的字符串,导致缓冲区溢出。

代码结果:

Enter a string: ThisIsAReallyLongStringThatWillOverflowTheBuffer You
entered: ThisIsAReallyLongStringThatWillOverflowTheBuffer

3.2 空白字符的处理:

问题:

scanf 使用 %s 读取字符串时,它会在遇到空白字符(空格、制表符、换行符等)时停止读取。

注意事项:

使用 fgets 可以正确处理包含空白字符的字符串,因为它会读取整行输入,包括空白字符。

代码示例及分析:

#include <stdio.h>

int main() {
    char str[20];

    printf("Enter a string with spaces: ");
    scanf("%s", str); // 在遇到空格时停止读取

    printf("You entered: %s\n", str);

    return 0;
}

在这个示例中,scanf 遇到空格就会停止读取,导致只能读取第一个单词。

代码结果:

Enter a string with spaces: Hello World
You entered: Hello

3.3 字符串结束标志:

问题:

C字符串以空字符 (‘\0’) 结尾,但某些输入函数可能不会自动添加结束标志。

注意事项:

确保在使用字符串时,它以空字符结尾,或者手动添加结束标志。
对于 printf 和 scanf 等函数,使用 %s 时,它们会自动处理字符串的结束标志。

代码示例及分析:

#include <stdio.h>

int main() {
    char str[10] = "Hello";

    printf("String: %s\n", str);

    return 0;
}

在这个示例中,字符串 “Hello” 以空字符 (‘\0’) 结尾,但是没有显示写入。

代码结果:

String: Hello

3.4 字符串长度的处理:

问题:

在使用字符串时,有时需要知道字符串的长度。

注意事项:

使用 strlen 函数获取字符串的长度。 如果你自己追踪字符串长度,请确保在字符串末尾始终有空字符。

代码示例及分析:

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

int main() {
    char str[] = "Hello, World!";
    int length = strlen(str);

    printf("Length of '%s' is %d\n", str, length);

    return 0;
}

在这个示例中,使用 strlen 函数获取了字符串的长度。

代码结果:

Length of 'Hello, World!' is 13

3.5格式化字符串的处理:

问题:

使用 printf 和 scanf 时,格式化字符串中的格式说明符需要与实际的数据类型匹配。

注意事项:

仔细匹配格式说明符和实际参数的数据类型,以避免未定义的行为。 使用 %s 时,确保提供的参数是有效的字符串地址。

代码示例及分析:

#include <stdio.h>

int main() {
    char str[] = "Hello";

    printf("String: %s\n", str); // 正确的格式化输出

    return 0;
}

在这个示例中,使用了 %s 格式说明符来输出字符串。

代码结果:

String: Hello

3.6 动态内存分配:

问题:

在动态分配内存存储字符串时,需要小心内存泄漏和释放错误。

注意事项:

使用 malloc 或 calloc 分配内存,并使用 free 释放。 在分配内存之前,确定字符串的最大长度,并确保分配足够的空间。

代码示例及分析:

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

int main() {
    char *dynamicStr = malloc(50 * sizeof(char));
    strcpy(dynamicStr, "Dynamic memory allocation");

    printf("Dynamic string: %s\n", dynamicStr);

    free(dynamicStr); // 释放动态分配的内存

    return 0;
}

在这个示例中,使用 malloc 分配了内存,然后使用 strcpy 复制了字符串,并最后使用 free 释放了内存。

代码结果:

Dynamic string: Dynamic memory allocation

这些注意事项有助于确保字符串输入输出的安全和正确性。

通过具体的代码示例和详细分析,我们讨论了如何正确使用标准库函数和格式说明符,以确保字符串的准确读取和输出。此外,我们还将涵盖动态内存分配与释放,以及字符串长度的处理,帮助读者全面理解C语言中与字符串相关的关键概念和最佳实践。通过学习本博客,希望您能够提升对C语言字符串操作的认识,培养安全而高效的编码习惯。

谢谢大家的阅读!

如果觉得这篇博客对你有用的话,别忘记三连哦。

我是甜美的江,让我们我们下次再见

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/364535.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024美赛C题全网最早思路 网球运动(持续更新)

2024美赛已经于今天早上6点准时公布题目。本次美赛将全程跟大家一起战斗冲刺O奖&#xff01;思路持续更新。 2024 MCM Problem C: Momentum in Tennis &#xff08;网球运动的势头&#xff09; 注&#xff1a;在网球运动中&#xff0c;"势头"通常指的是比赛中因一系…

Jmeter学习系列之五:线程组(Thread Group)

前言 线程组是一系列线程的集合,每一个线程代表着一个正在使用应用程序的用户。在 jmeter 中,每个线程意味着模拟一个真实用户向服务器发起请求。 在 jmeter 中,线程组组件运行用户设置线程数量、初始化方式等等配置。 例如,如果你设置线程数为 100,那么 jmeter 将创建…

2024美赛数学建模C题思路分析 - 网球的动量

1 赛题 问题C&#xff1a;网球的动量 在2023年温布尔登绅士队的决赛中&#xff0c;20岁的西班牙新星卡洛斯阿尔卡拉兹击败了36岁的诺瓦克德约科维奇。这是德约科维奇自2013年以来首次在温布尔登公开赛失利&#xff0c;并结束了他在大满贯赛事中历史上最伟大的球员之一的非凡表…

双非本科准备秋招(13.1)—— 力扣 栈、队列与堆

1、103. 二叉树的锯齿形层序遍历 昨天做的二叉树的层序遍历&#xff0c;把代码直接拿过来。 这个题要求的是一个Z型遍历&#xff0c;如下图。 用一个变量f记录正反顺序&#xff0c;然后使用LinkedList记录答案&#xff0c;下图可以看到LinkedList继承了Deque&#xff0c;所以…

k8s二进制及负载均衡集群部署详解

目录 常见部署方式 二进制部署流程 环境准备 操作系统初始化配置 关闭防火墙 配置SELinux 关闭SWAP 根据规划设置主机名 在master添加hosts&#xff0c;便于主机名解析 调整内核参数 配置时间同步 部署docker引擎 在所有node节点部署docker引擎 部署etcd集群 签发…

【文本到上下文 #8】NLP中的变形金刚:解码游戏规则改变者

一、说明 欢迎来到我们对不断发展的自然语言处理 &#xff08;NLP&#xff09; 领域的探索的第 8 章。在本期中&#xff0c;我们将重点介绍一项重塑 NLP 格局的突破性创新&#xff1a;Transformers。在我们之前对 seq2seq 模型、编码器-解码器框架和注意力机制的讨论之后&#…

flutter如何实现省市区选择器

前言 当我们需要用户填写地址时&#xff0c;稳妥的做法是让用户通过“滚轮”来滑动选择省份&#xff0c;市&#xff0c;区&#xff0c;此文采用flutter的第三方库来实现这一功能&#xff0c;比调用高德地图api简单一些。 流程 选择库 这里我选择了一个最近更新且支持中国的…

ABAP Range Table:RANGES的使用

目录 Range TableRANGERANGES RANGE的四个参数SIGNOPTIONLOWHIGH示例程序 Range Table 1、Range Table 概述 RANGE TABLE为 SAP R/3系统标准内表的一种&#xff0c;结构与 Selection Table 一致&#xff0c; 由 SIGN, OPTION, LOW 和 HIGH字段组成&#xff1b; 可以通过 TYPE…

面试宝典之深谈JVM

面试宝典之深谈JVM 1.为什么需要JVM&#xff0c;不要JVM可以吗&#xff1f; 1.JVM可以帮助我们屏蔽底层的操作系统 一次编译&#xff0c;到处运行 2.JVM可以运行Class文件 2.JDK&#xff0c;JRE以及JVM的关系 3.我们的编译器到底干了什么事&#xff1f; 仅仅是将我们的 .ja…

【动态规划】【C++算法】1340. 跳跃游戏 V

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1340跳跃游戏 V 给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到&#xff1a; i x &#xff0c;其中 i x < arr.length 且 0 < x…

用户界面(UI)、用户体验(UE)和用户体验(UX)的差异

对一个应用程序而言&#xff0c;UX/UE (user experience) 设计和 UI (user interface) 设计非常重要。UX设计包括可视化布局、信息结构、可用性、图形、互动等多个方面。UI设计也属于UX范畴。正是因为三者在一定程度上具有重叠的工作内容&#xff0c;很多从业多年的设计师都分不…

2024年美国大学生数学建模A题思路分析 - 资源可用性和性别比例

# 1 赛题 问题A&#xff1a;资源可用性和性别比例 虽然一些动物物种存在于通常的雄性或雌性性别之外&#xff0c;但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1&#xff1a;1&#xff0c;但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。…

STM32CubeIDE 使用标准库来编写程序

这些天我想找一个软件来实现软件的替代。就找到了st 的生态。可是现在st 生态都在极力的推荐HAL 库,但是习惯了标准库的朋友们,还不是很习惯。 先上总结一下,为了好记忆: 一、 在编译栏做如下设置 1、头文件设置 2、源文件设置 二、指定具体的预定义宏 1、USE_STDPERIPH_D…

angular 表单FormGroup笔记

一、校验 1、校验提示 <nz-form-item><nz-form-label>手机号码</nz-form-label><nz-form-control [nzErrorTip]"mobileTemplate"><input nz-input formControlName"mobile" placeholder"请输入" /><ng-templ…

【Java并发】聊聊Disruptor背后高性能的原理

为什么需要Disruptor 对于单机生产者消费者来说&#xff0c;JUC本身提供了阻塞队列&#xff0c;ArrayBlockingQueue、LinkedBlockingQueue 等&#xff0c;但是为了保证数据安全&#xff0c;使用了reentrantLock进行加锁操作会影响性能&#xff0c;另一方面&#xff0c;本身如果…

正点原子--STM32中断系统学习笔记(1)

1、什么是中断&#xff1f; 原子哥给出的概念是这样的&#xff1a;打断CPU正常执行的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff0c;就叫中断。 当发生中断时&#xff0c;当前执行的程序会被暂时中止&#xff0c;进而进入中断处理函…

05:容器镜像技术揭秘|发布容器服务器|私有镜像仓库

容器镜像技术揭秘&#xff5c;发布容器服务器&#xff5c;私有镜像仓库 创建镜像使用commit方法创建自定义镜像。Dockerfile打包镜像创建apache服务镜像制作 php 镜像 微服务架构创建nginx镜像 发布服务通过映射端口发布服务容器共享卷 docker私有仓库 创建镜像 使用commit方法…

Hadoop3.x基础(3)- MapReduce

来源: B站尚硅谷 目录 MapReduce概述MapReduce定义MapReduce优缺点优点缺点 MapReduce核心思想MapReduce进程常用数据序列化类型MapReduce编程规范WordCount案例实操本地测试提交到集群测试 Hadoop序列化序列化概述自定义bean对象实现序列化接口&#xff08;Writable&#xff…

Nicn的刷题日常之BC68 X形图案

1.题目描述 KiKi学习了循环&#xff0c;BoBo老师给他出了一系列打印图案的练习&#xff0c;该任务是打印用“*”组成的X形图案。 输入描述&#xff1a; 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜…