当前位置: 首页 > article >正文

C/C++混合读入cin与scanf问题

因为C/C++在某些时候是如此的融洽,以至于很多时候可能会混用,就比如 scanf与cin或getline(cin, ..)这是一个严肃的问题。因为随意混用,可能导致,在某些特殊时刻,读取混乱。所以本篇的意义就是为了缕清混用机制

一、scanf的应用方式

1、初级用法

scanf时 C 语言中的一个输入函数,用于从标准输入读取格式化输入,他被申明在头文件stdio.h

#include <stdio.h>

int main() {
	int a, b;
	printf("请输入两个整数:");
	scanf("%d %d", &a, &b);
	printf("你输入的整数是:%d 和 %d\n", a, b);
	return 0;
}

注意事项
1、空白字符: scanf 会跳过输入中的空白字符(如空格、制表符和换行符)。
2、非空白字符: scanf 会剔除与格式说明符不匹配的字符。
3、缓冲区残留: 输入缓冲区中的残留字符可能会影响后续的输入操作,可以使用 getchar() 或 fflush(stdin) 清理缓冲区

2、中级用法

格式化 · 单个读取
%d:十进制 -> int
%lld:十进制 -> long long
%f:浮点数
%c:一个字符
%s:一个字符串
%p:读取指针
整行读取
scanf( "%[^\n]" , str ); 整行读取。

格式控制符 %[] 的作用
%[] 是 scanf 函数中的一种特殊格式控制符,也被称作扫描集(scan set)。它的作用是读取符合指定字符集合的连续字符序列,直到遇到不在该集合中的字符为止。其基本语法格式为 %[字符集合]。

%[^\n] 的具体含义

  • ^ 是一个取反符号,当它出现在 %[] 中的开头位置时,表示读取除了方括号内指定字符之外的所有字符。
  • \n 代表换行符。

所以,%[^\n] 的意思就是读取除换行符之外的所有字符,直到遇到换行符才停止读取,这样就能实现整行读取的效果。

3、高级用法

1、处理缓冲区残留问题:int a; char c; scanf("%d", &a); getchar(); // 清理缓冲区中的换行符 scanf("%c", &c); 等等…

二、cin的应用方式

1、初级

基本输入cin (空格 / Tab / 换行分隔)

int a;
double b;
string s;

cin >> a >> b >> s;  // 依次读取整型、浮点型、字符串
  • 特点:自动跳过空白符(空格、制表符、换行)
  • 注意:无法读取含空格的字符串(会在空格处截断)

读取整行getline (含空格)

string line; // 因为要读取一整行,固需用 string
getline(cin, line);  // 读取整行(包括空格) !不会在结尾处留下/n
  • 典型问题:混合使用>> 和 getline 时,需先清除缓冲区:
int num;
string text; 

cin >> num;
cin.ignore();  // 清除缓冲区的换行符
getline(cin, text);

2、中级

错误处理与验证

int age;
while (true) {
    cout << "Enter age: ";
    if (cin >> age) {  // 检查输入是否合法
        break;
    } else {
        cin.clear();  // 清除错误状态
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清空缓冲区
        cout << "Invalid input!" << endl;
    }
}
  • 关键方法
    • cin.clear():清除错误标志(如输入非数字时触发的 failbit)
    • cin.ignore():清空缓冲区中的无效内容

按特定字符数量读取

string part1, part2;
cin >> part1;                  // 读取到第一个空格
cin.ignore(5);           // 在读5个字符
getline(cin, part2, ',');      // 读取直到逗号

读取单个字符

char ch;
cin.get(ch);       // 读取单个字符(包括空格/换行)
// 或
ch = cin.get();    // 函数返回值形式

三、scanf与cin、getline混合使用

其实,上方说了那么多,只不过是为此,做铺垫

string p1,p2;
scanf("%s",&p1); 
cin.ignore(); // cin.ignore()默认清除 1 个字符,也就是\n
getline(cin,p2);

将 cin 与 scanf 反转,就不用担心此问题

string p1,p2;
getline(cin,p2); // geline() 会把末尾处的 '\n' 吸收掉
scanf("%s",&p1); 

若有问题,请及时私信。



http://www.kler.cn/a/542773.html

相关文章:

  • NO.13十六届蓝桥杯备战|条件操作符|三目操作符|逻辑操作符|!||||(C++)
  • bug-ant下拉框解决下拉框跟随表单容器(指定下拉框挂载容器):getPopupContainer=“p=>p.parentNode“
  • Vue项目--动画效果的改变
  • 开发完的小程序如何分包
  • 活动预告 | Power Hour: Copilot 引领商业应用的未来
  • 深度剖析责任链模式
  • Go1.24 strings包增加的新方法
  • java安全中的类加载
  • 【Apache Paimon】-- 作为一名小白,如何系统地学习 Apache paimon?
  • Unity使用iTextSharp导出PDF-05页面事件
  • RESTful API 和 WebSocket 的区别
  • BootstrapBlazor Table组件 使用的注入 数据服务 实现类:使用 EF Core
  • Spring Cloud 07 - 分布式链路追踪APM
  • Acwing-基础算法课笔记之基础算法(差分)
  • Wiki文档转换为Word技术
  • 使用C语言实现MySQL数据库的增删改查操作指南
  • Java90道面试题
  • 利用邮件合并将Excel的信息转为Word(单个测试用例转Word)
  • 创建和使用 Python 虚拟环境(使用Python自带的venv模块)
  • Spring Boot 中加载多个 YAML 配置文件
  • Ansible中常用的playbook命令
  • Anaconda 安装指南:Windows、macOS 和 Linux 的详细安装步骤
  • 解码DeepSeek家族系列:大语言模型赛道上的黑马传奇
  • 云消息队列 ApsaraMQ Serverless 演进:高弹性低成本、更稳定更安全、智能化免运维
  • python基础入门:附录:常用第三方库推荐(NumPy、Django等)
  • 【3.Git与Github的历史和区别】