跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C/C++ 输入输出详解:OJ 场景与性能优化

综述由AI生成深入解析 C/C++ 输入输出机制,涵盖 OJ 常见测试用例处理模式,对比了含空格字符串及数字处理的技巧。重点分析 scanf/printf 与 cin/cout 在格式控制与性能上的差异,通过代码演示 IO 同步关闭等优化方案,帮助开发者在算法竞赛中避免超时并写出高效代码。

www发布于 2026/3/27更新于 2026/6/918 浏览
C/C++ 输入输出详解:OJ 场景与性能优化

C/C++ 输入输出详解:OJ 场景与性能优化

前言

在编程世界中,输入输出(I/O)是交互的基础。C 和 C++ 提供了强大的 I/O 机制,从简单的 printf 和 scanf 到 C++ 的流式操作 cin 和 cout,看似简单,实则暗藏玄机。许多开发者在使用过程中可能会遇到缓冲区问题、格式控制陷阱、性能瓶颈,甚至安全性隐患。本文将针对 C/C++ 输入输出的常见问题进行一一梳理。

1. OJ 题目输入情况汇总

在竞赛的 OJ 题目中,输入场景通常总结为以下几类:

1.1 单组测试用例

此类题目只需读取一次数据并输出结果。

示例:计算 (a+b)/c 的值 参考代码:

#include <iostream>
using namespace std;

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    cout << (a + b) / c << endl;
    return 0;
}

示例:与 7 无关的数 思路:先输入 n,循环产生 1~n 的数字,找出与 7 无关的正整数,最后求平方和。与 7 相关的条件包括:被 7 整除、个位是 7、十位是 7。 参考代码:

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int i = 1;
    int sum = 0;
    while (i <= n) {
        if (i % 7 != 0 && i % 10 != 7 && i / 10 != 7) {
            sum += (i * i);
        }
        i++;
    }
    cout << sum << endl;
    return 0;
}

1.2 多组测试用例

1.2.1 测试数据组数已知

当题目明确告知有 n 组数据时,通常使用 while(n--) 循环。

示例:多组输入 a+b II 参考代码:

#include <iostream>
using namespace std;

int main() {
    int n; // 表示数据组数
    cin >> n;
    int a, b; // 每行输入的 a,b 值
    while (n--) {
        cin >> a >> b;
        cout << a + b << endl;
    }
    return 0;
}

示例:斐波那契数列 特点:前两个数的和是第三个数。有多种解法,如循环嵌套、预处理数组或递归。 参考代码(预处理数组):

#include <iostream>
using namespace std;

int main() {
    int n, a, i;
    int ret[35] = {0, 1, 1};
    for (i = 3; i < 30; i++) {
        ret[i] = ret[i - 1] + ret[i - 2];
    }
    cin >> n;
    while (n--) {
        cin >> a;
        cout << ret[a] << endl;
    }
    return 0;
}
1.2.2 测试数据组未知

当不知道有多少组数据时,通常利用 while(cin >> ...) 来判断输入是否结束。

示例:多组输入 a+b 参考代码:

#include <iostream>
using namespace std;

int main() {
    int a, b;
    while (cin >> a >> b) {
        cout << a + b << endl;
    }
    return 0;
}

这里 cin >> a >> b 返回流对象引用,在布尔上下文中检查流状态。如果读取成功则为 true,否则为 false。

1.2.3 特殊值结束测试数据

某些题目以特定数值(如 0 0)作为结束标志。

示例:多组数据 a+b III 参考代码:

#include <iostream>
using namespace std;

int main() {
    int a = 0, b = 0;
    while (cin >> a >> b, a && b) {
        cout << a + b << endl;
    }
    return 0;
}

这里使用了逗号表达式,从左往右计算,结果为最后一个表达式的值。

2. 输入时特殊技巧

2.1 含空格字符串的特殊处理方式

读取含空格的字符串可以使用 fgets、scanf、getchar 或 getline。但有时将空格隔开的单词单独处理更方便。

练习:统计数字字符个数 做法一:读取整个带空格的字符串分析。

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    getline(cin, s);
    int ret = 0;
    for (auto ch : s) {
        if (ch >= '0' && ch <= '9') {
            ret++;
        }
    }
    cout << ret << endl;
    return 0;
}

做法二:按照多个单词分析。

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    int cnt = 0;
    while (cin >> s) {
        for (auto c : s) {
            if (c >= '0' && c <= '9') cnt++;
        }
    }
    cout << cnt << endl;
    return 0;
}

判断数字字符也可以使用 isdigit(ch) 函数简化。

2.2 数字的特殊处理方式

输入 123 时,程序会根据变量类型将其解析为整型或字符串。根据实际需求选择处理方式。

练习:小乐乐改数字 法一:当做整数读取,通过 % 10 和 / 10 获取每一位。

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int n;
    int i = 0, ret = 0;
    cin >> n;
    while (n) {
        if (n % 10 % 2 == 1) {
            ret += pow(10, i);
        }
        n /= 10;
        i++;
    }
    cout << ret << endl;
    return 0;
}

法二:当做字符串处理,利用 ASCII 码奇偶性判断。

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    cin >> s;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] % 2) {
            s[i] = '1';
        } else {
            s[i] = '0';
        }
    }
    cout << stoi(s) << endl;
    return 0;
}

stoi 是 C++11 标准引入的字符串转换函数。

3. scanf/printf 和 cin/cout 的对比

scanf 和 printf 是 C 语言标准函数,cin 和 cout 是 C++ 流对象。各有优缺点。

3.1 格式控制差异

  • scanf 和 printf 需要手动指定格式字符串,容易出现格式错误,但格式化输出更精确直观。
  • cin 和 cout 自动识别类型,避免格式化错误,更易用。
  • 浮点数输出时,cout 默认忽略多余 0,printf 默认打印 6 位小数。
#include <cstdio>
#include <iostream>
using namespace std;

int main() {
    float a = 3.50;
    double d = 16.50;
    cout << "cout: " << a << " " << d << endl;
    printf("printf: %f %lf\n", a, d);
    return 0;
}

3.2 性能差异

结论:scanf 和 printf 通常比 cin 和 cout 快。 原因:cin 和 cout 为了兼容 C 语言,封装更复杂。且默认情况下,cin 与 cout 存在绑定关系,每次读取都会刷新输出缓冲区。在大数据量输入时,cin/cout 容易导致 Time Limit Exceeded。

案例演示 在大量数据输入场景下,使用 cin 可能超时,而 scanf 能通过。

3.2.2 优化方案和演示

可以通过以下代码优化 cin/cout 性能:

ios::sync_with_stdio(false); // 取消 C 语言输入输出缓冲区的同步
cin.tie(0);                  // 取消 cin 和 cout 的绑定

优化后,cin/cout 的性能可接近 scanf/printf。

总结

  1. 数据量较小(10^6 以内),两者皆可。
  2. 数据量较大(10^9 左右),推荐使用 scanf/printf 或优化后的 cin/cout。
  3. 极端大规模 IO 可使用快速读写模板。

结语

掌握输入输出的底层机制和陷阱,才能写出健壮高效的代码。从缓冲策略到格式控制,每个细节都可能成为调试时的关键。希望这篇文章能给各位对 C/C++ 的输入输出带来不一样的理解。

目录

  1. C/C++ 输入输出详解:OJ 场景与性能优化
  2. 前言
  3. 1. OJ 题目输入情况汇总
  4. 1.1 单组测试用例
  5. 1.2 多组测试用例
  6. 1.2.1 测试数据组数已知
  7. 1.2.2 测试数据组未知
  8. 1.2.3 特殊值结束测试数据
  9. 2. 输入时特殊技巧
  10. 2.1 含空格字符串的特殊处理方式
  11. 2.2 数字的特殊处理方式
  12. 3. scanf/printf 和 cin/cout 的对比
  13. 3.1 格式控制差异
  14. 3.2 性能差异
  15. 3.2.2 优化方案和演示
  16. 结语
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 解决 JPA 中 new Date() 插入数据库时间差 8 小时问题
  • ESP32 小智 AI 机器人语音对话系统设计与云端部署
  • 国内首个教育垂直大模型落地:机遇、挑战与伦理风险
  • 计算机技能如何助力职业拓展与转型
  • 注意力机制与 Transformer 模型实战
  • 注意力机制与 Transformer 模型架构及实战详解
  • 自然语言处理在医疗健康领域的应用与实战
  • ChatGLM3 大模型本地化部署与应用开发技术指南
  • 安路 FPGA 下载器驱动安装与测试指南
  • C# 后端导出 Excel 并实现前端直接下载方案
  • Flutter serial 库鸿蒙化适配:Web 串口通信与硬件连接实战
  • OpenClaw 接入自定义模型及 WebUI 智能操作实战
  • GESP2023年12月C++二级认证选择题解析(9-15题)
  • 分布式系统设计与实战:Java 微服务架构落地
  • OpenClaw 接入自定义模型并通过 WebUI 实现智能操作
  • PptxGenJS 实战:利用 JavaScript 自动化生成专业 PPT
  • 大语言模型 LLM 解决 AI 幻觉方法深度分析
  • 前端组件库实战:告别重复造轮子
  • 大模型学习路径(一):人工智能与大模型基础概述
  • NativeScript-Vue 跨平台原生应用开发实战

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online