【C++】字符数|组输入与处理全解析


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯1. 基础方法:scanf 和 cin 的使用
    • 1.1 使用 scanf 实现简单字符串输入
      • 示例代码
      • 行为分析
      • 示例输入与输出
      • 优缺点
      • 改进建议
    • 1.2 使用 cin 实现字符串输入
      • 示例代码
      • 行为分析
      • 示例输入与输出
      • 优缺点
      • 改进建议
  • 💯2. 从数组特定位置开始输入
    • 2.1 使用 scanf 实现偏移输入
      • 示例代码
    • 2.2 使用 cin 实现偏移输入
      • 示例代码
    • 行为分析
  • 💯3. 读取整行字符串:解决空格问题
    • 3.1 使用 scanf 的格式修饰符
      • 示例代码
      • 行为分析
      • 示例输入与输出
      • 优缺点
    • 3.2 使用 fgets
      • 示例代码
      • 行为分析
      • 示例输入与输出
      • 优缺点
    • 3.3 使用 getchar 逐字符读取
      • 示例代码
      • 行为分析
      • 优缺点
  • 💯4. 总结与建议
    • 方法对比
    • 推荐实践


在这里插入图片描述


💯前言

  • 在 C++ 编程中,字符串输入与处理是一个基础而又非常重要的环节。在实际开发中,我们常常会遇到处理用户输入字符串的需求,无论是简单的单词输入,还是带有空格的整行输入,都需要对相关的函数和方法有一个全面的理解。本文将通过具体的代码示例和深入的分析,全面梳理 C++ 中字符串输入的常用方法,包括 scanfcinfgetsgetchar 等,同时补充扩展了其工作原理和最佳实践,帮助读者系统地掌握这一内容。
    C++ 参考手册
    在这里插入图片描述
    字符数组是 C 和 C++ 中处理字符串的重要工具。在输入字符串时,我们需要注意以下几个关键问题:
  1. 空格处理问题:默认的输入函数如 scanfcin 会在遇到空格时停止读取,这会限制我们处理多词字符串(如带空格的句子)。
  2. 安全性问题:如果输入的字符串长度超过数组大小,可能导致缓冲区溢出,造成程序运行错误甚至潜在的安全漏洞。
  3. 灵活性问题:如何根据需求选择合适的输入方式,如逐字符读取或限制输入长度。

接下来,我们将以实际的代码示例为基础,从基础到高级,一步步探讨如何在 C 和 C++ 中处理字符数组输入。


💯1. 基础方法:scanf 和 cin 的使用

1.1 使用 scanf 实现简单字符串输入

示例代码

#include <cstdio>

int main() {
    char arr[20] = {0}; // 初始化字符数组
    scanf("%s", arr); // 输入到字符数组中
    printf("%s", arr); // 输出字符数组内容
    return 0;
}

行为分析

  1. 读取规则:scanf("%s", arr) 从标准输入读取一个字符串,遇到空格、换行符或制表符时停止。
  2. 自动添加结束符:读取的字符串末尾会自动加上 \0,以标识字符串结束。

示例输入与输出

  • 输入:abc def
  • 输出:abc

优缺点

  • 优点:代码简单,适用于读取单个单词的场景。
  • 缺点:无法读取包含空格的字符串,如句子或地址。
  • 安全隐患:如果输入字符串长度超过数组容量,会导致缓冲区溢出。

改进建议

为了避免溢出,可以使用格式化限制符,如:

scanf("%19s", arr); // 限制最多读取 19 个字符

1.2 使用 cin 实现字符串输入

示例代码

#include <iostream>
using namespace std;

int main() {
    char arr[20] = {0};
    cin >> arr; // 输入到字符数组中
    cout << arr << endl; // 输出字符数组内容
    return 0;
}

行为分析

  1. 默认行为:cin 会忽略输入的空白字符(如空格、换行符),并在遇到下一个空白字符时停止。
  2. 末尾加 \0:和 scanf 类似,读取的字符串末尾会自动加上 \0

示例输入与输出

  • 输入:abc def
  • 输出:abc

优缺点

  • 优点:比 scanf 更加现代化,推荐在 C++ 中使用。
  • 缺点:同样无法处理包含空格的字符串。
  • 安全性:cin 不会限制输入长度,因此也可能导致缓冲区溢出。

改进建议

为了避免输入溢出,推荐使用 std::getline(见后续内容)替代 cin


💯2. 从数组特定位置开始输入

有时,我们希望从字符数组的特定位置(而非起始位置)开始存储输入数据。这可以通过地址偏移实现。

2.1 使用 scanf 实现偏移输入

示例代码

#include <cstdio>

int main() {
    char arr[20] = {0};
    scanf("%s", arr + 2); // 从 arr[2] 开始存储输入
    printf("%s", arr + 2); // 输出从 arr[2] 开始的内容
    return 0;
}

2.2 使用 cin 实现偏移输入

示例代码

#include <iostream>
using namespace std;

int main() {
    char arr[20] = {0};
    cin >> (arr + 1); // 从 arr[1] 开始存储输入
    cout << (arr + 1) << endl; // 输出从 arr[1] 开始的内容
    return 0;
}

行为分析

  • 通过数组地址偏移(如 arr + 2),可以从数组的特定位置开始存储输入数据。
  • 要注意数组的大小是否足够,避免越界。

💯3. 读取整行字符串:解决空格问题

为了读取包含空格的整行字符串,可以选择以下方法。

3.1 使用 scanf 的格式修饰符

示例代码

#include <cstdio>

int main() {
    char arr[50] = {0};
    scanf("%[^\n]", arr); // 读取整行,直到遇到换行符
    printf("%s\n", arr);
    return 0;
}

行为分析

  • %[^\n]:表示从输入中读取所有字符,直到遇到换行符为止。
  • 自动加结束符:读取完毕后,scanf 会自动在字符串末尾添加 \0

示例输入与输出

  • 输入:abc def
  • 输出:abc def

优缺点

  • 优点:可以读取包含空格的整行字符串。
  • 缺点:需要手动限制输入长度,防止溢出。

3.2 使用 fgets

在这里插入图片描述

在这里插入图片描述

示例代码

#include <cstdio>

int main() {
    char arr[50] = {0};
    fgets(arr, sizeof(arr), stdin); // 从标准输入读取一行
    printf("%s\n", arr);
    return 0;
}

行为分析

  • 读取规则:fgets 会读取最多 sizeof(arr) - 1 个字符,并在末尾自动加上 \0
  • 换行符保留:如果输入包含换行符,fgets 会将其保留在结果中。

示例输入与输出

  • 输入:abc def
  • 输出:abc def\n

优缺点

  • 优点:更加安全,避免缓冲区溢出。
  • 缺点:需要手动处理换行符(如果不需要换行符)。

3.3 使用 getchar 逐字符读取

示例代码

#include <cstdio>

int main() {
    char arr[50] = {0};
    int ch, i = 0;
    while ((ch = getchar()) != '\n' && i < sizeof(arr) - 1) {
        arr[i++] = ch;
    }
    printf("%s\n", arr);
    return 0;
}

行为分析

  • 逐字符读取:getchar 每次从输入中读取一个字符,直到遇到换行符为止。
  • 灵活性高:可以根据需要自定义读取逻辑,例如跳过某些字符。

优缺点

  • 优点:逐字符读取,灵活控制输入逻辑。
  • 缺点:实现复杂,容易出错。

💯4. 总结与建议

方法对比

方法支持空格输入自动限制长度使用难度推荐程度
scanf("%s")简单
scanf("%[^\n]")中等⭐⭐
fgets简单⭐⭐⭐⭐⭐
getchar中等⭐⭐⭐

推荐实践

  1. 读取单词:使用 scanf("%s")cin
  2. 读取整行:推荐使用 fgets,更加安全。
  3. 逐字符处理:在需要灵活读取的场景下,使用 getchar

通过合理选择方法,我们可以高效且安全地处理用户输入的字符串内容。如果您有进一步的问题或应用场景,欢迎深入探讨!


在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

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

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

相关文章

Python爬虫教程——7个爬虫小案例(附源码)_爬虫实例

本文介绍了7个Python爬虫小案例&#xff0c;包括爬取豆瓣电影Top250、猫眼电影Top100、全国高校名单、中国天气网、当当网图书、糗事百科段子和新浪微博信息&#xff0c;帮助读者理解并实践Python爬虫基础知识。 包含编程资料、学习路线图、源代码、软件安装包等&#xff01;【…

apex安装

安装过程复杂曲折&#xff0c;网上说的很多办法&#xff0c;貌似成功了&#xff0c;实际还是没起作用。 先说成功过程&#xff0c;执行下面命令&#xff0c;安装成功&#xff08;当然&#xff0c;前提是你要先配置好编译环境&#xff09;&#xff1a; &#xff08;我的环境&a…

谷粒商城-高级篇-Sentinel-分布式系统的流量防卫兵

1、基本概念 1.1、熔断降级限流 1、什么是熔断 A 服务调用 B 服务的某个功能&#xff0c;由于网络不稳定问题&#xff0c;或者 B 服务卡机&#xff0c;导致功能时间超长。如果这样子的次数太多。我们就可以直接将 B 断路了&#xff08; A 不再请求 B 接口&#xff09;&#…

Django的runserver

当年执行 python manage runserver命令时 1. 先执行 runserver 中的 handle方法 2. 执行 self.run()方法 3. 执行 self.inner_run() 3.1 inner_run 下 run方法的封装 3.1.1 接着看 handle 怎么来的 封装了一个方法 接着找返回函数 3.1.2在 basehttp 下 3.1.3 get_wsgi_appl…

MySQL 如何赶上 PostgreSQL 的势头?

原文地址 我与 MySQL 社区的前辈交谈时&#xff0c;经常遇到这个问题&#xff1a;「为什么 MySQL 这么棒&#xff0c;而且&#xff08;至少根据 DB-Engines 的计算&#xff09;仍然比 PostgreSQL 更流行&#xff1b;但它的地位在下降&#xff0c;PostgreSQL 却势不可挡地越来越…

微信小程序中的 storage(本地存储)和内存是两个完全不同的存储区域

这是一个非常关键且容易混淆的概念 既然 this.globalData.appId appId 是将 appId 存储在内存中&#xff0c;为什么微信小程序中的 wx.getStorage 和 wx.setStorage&#xff08;本地存储&#xff09;中没有 appId&#xff0c;并且您提出了一个非常重要的疑问&#xff1a;stor…

c/c++ 里的进程间通信 , 管道 pipe 编程举例

&#xff08;1&#xff09;以下是一个网上的使用 pipe 编程的范例&#xff1a; #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h>int main() {int pipefd…

java项目之网上租贸系统源码(springboot+mysql+vue)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的网上租贸系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于Spring Boot的网上租贸…

数据库回滚:大祸临头时

原文地址 什么是数据库回滚&#xff1f; 数据库技术中&#xff0c;回滚是通过撤销对数据库所做的一项或多项更改&#xff0c;将数据库返回到先前状态的操作。它是维护数据完整性和从错误中恢复的重要机制。 什么时候需要数据库回滚&#xff1f; 数据库回滚在以下几个场景中很…

Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式

业务场景 在目前常见的中后台管理系统中&#xff0c;比较常见的是固定的布局方式包裹页面&#xff0c;但一些特殊页面&#xff0c;比如&#xff1a;登录页面、注册页面、忘记密码页面这些页面是不需要布局包裹的。 但在 Next.js AppRouter 中&#xff0c;必须包含一个根布局文…

【UE5 C++课程系列笔记】23——多线程基础——AsyncTask

目录 概念 函数说明 注意事项 &#xff08;1&#xff09;线程安全问题 &#xff08;2&#xff09;依赖特定线程执行的任务限制 &#xff08;3&#xff09;任务执行顺序和时间不确定性 使用示例 概念 AsyncTask 允许开发者将一个函数或者一段代码逻辑提交到特定的线程去执…

2025-01-04 Unity插件 YodaSheet1 —— 插件介绍

文章目录 1 介绍2 工作原理2.1 ScriptableObject -> YadeSheetData2.2 YadeDatabase 存储多个 YadeSheetData 3 用途4 缺点5 推荐 1 介绍 ​ Yade 提供类似于 Excel 或者 Google Sheets 的表格编辑器&#xff0c;可以轻松地在 Unity 编辑器中 编辑&#xff0c;搜索&#xf…

【阅读笔记】基于FPGA的红外图像二阶牛顿插值算法的实现

图像缩放技术在图像显示、传输、分析等多个领域中扮演着重要角色。随着数字图像处理技术的发展&#xff0c;对图像缩放质量的要求也越来越高。二阶牛顿插值因其在处理图像时能够较好地保持边缘特征和减少细节模糊&#xff0c;成为了图像缩放中的一个研究热点。 一、 二阶牛顿插…

C语言 扫雷程序设计

目录 1.main函数 2.菜单打印menu函数 3.游戏game函数 4.宏定义 5.界面初始化 6.打印界面 7.设置雷 8.统计排查坐标周围雷的个数 9.排查雷 10.总代码 test.c代码 game.h代码 game.c代码 结语&#xff1a; 一个简单的扫雷游戏&#xff0c;通过宏定义可以修改行列的…

如何有效搭建在线培训知识库

在当今快速发展的教育行业&#xff0c;知识的更新速度日益加快&#xff0c;教育机构和企业需要为学员提供持续的学习资源和培训支持。在线培训知识库的搭建成为实现这一目标的重要手段。一个有效的在线培训知识库不仅能够帮助学员系统地学习和掌握知识&#xff0c;还能为教师和…

Android Audio基础(54)——数字音频接口 I2S、PCM(TDM) 、PDM

1. 概述 本文介绍的数字音频接口全部是硬件接口,是实际的物理连线方式,即同一个PCB板上IC芯片和IC芯片之间的通讯协议。 PCM、PDM也可以用于表示音频编码格式,。编码格式是指模拟信号数字化的方式。 I2S和PCM(TDM)接口传输的数据是PCM格式的音频数据。这两种协议是最为常见…

STM32之CAN通讯(十一)

STM32F407 系列文章 - CAN通讯&#xff08;十一&#xff09; 目录 前言 一、CAN 二、CAN驱动电路 三、CAN软件设计 1.CAN状态初始化 2.头文件相关定义 3.接收中断服务函数 4.用户层使用 1.用户层相关定义 2.发送数据 3.接收数据 1.查询方式处理 2.中断方式处理 3…

第31天:Web开发-PHP应用TP框架MVC模型路由访问模版渲染安全写法版本漏洞

#知识点 1、安全开发-框架技术-ThinkPHP 2、安全开发-框架安全-版本&写法 3、安全开发-ThinkPHP-代码审计案例 类别 组件/框架 说明 [Web框架] Laravel 现代化、功能全面的框架&#xff0c;适合大多数Web应用。 Symfony 高度模块化、功能强大的框架&#xff0c;适…

量子计算遇上人工智能:突破算力瓶颈的关键?

引言&#xff1a;量子计算遇上人工智能——突破算力瓶颈的关键&#xff1f; 在数字化时代的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变着我们的生活&#xff0c;从语音助手到自动驾驶&#xff0c;从医学诊断到金融分析&#xff0c;无不彰显其…

英伟达 RTX 5090 显卡赋能医疗大模型:变革、挑战与展望

一、英伟达 RTX 5090 与 RTX 4090 技术参数对比 1.1 核心架构与制程工艺 在探讨英伟达 RTX 4090 与 RTX 5090 的差异时&#xff0c;核心架构与制程工艺无疑是最为关键的基础要素&#xff0c;它们从根本上决定了两款显卡的性能上限与应用潜力。 1.1.1 核心架构差异 RTX 4090…