前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >浅谈 C/C++ 的输入输出

浅谈 C/C++ 的输入输出

作者头像
浪漫主义狗
发布于 2023-03-01 05:35:50
发布于 2023-03-01 05:35:50
5K00
代码可运行
举报
文章被收录于专栏:HAUE_LYS'BlogHAUE_LYS'Blog
运行总次数:0
代码可运行

0. 叠甲,过


本人水平有限,语言组织能力低下,不保证绝佳的阅读体验,也不保证内容完全准确,如有错误和建议,欢迎指出。才怪


1. 谈谈输入输出缓冲区


1.1 基本概念


你先别急,我知道你很急,但是别急,所以你先别急

在了解输入输出输出缓冲区时,需要明确以下几个基本概念:

  • 输入输出流
  • 标准输入输出流
  • 文件输入输出流

输入输出流

  • 输入输出流是一种数据传输的概念。
  • 构成计算机的其中之一部件为 I/O 设备,指的是用于从程序内部向外部设备(屏幕、打印机等)或从外部设备向程序内部传输数据的设备(鼠标、键盘等);
  • 计算机中通过 I/O 设备进行与用户之间的数据交互,而为了适应不同的设备之间数据的传输,提出了输入输出流的概念。
  • 即,输入输出流就是一种统一的数据输入输出协议,为不同的设备之间传递数据时提供一致的接口

标准输入输出流

  • 标准输入输出流是指程序与外部设备(例如键盘和显示器)之间的输入输出
  • C 语言中:
    • C 标准库中,标准输入流输出流分别是 stdinstdout,另外还有标准错误流 stderr
    • 使用 <stdio.h> 头文件里的 scanf() 函数和 printf() 函数。
  • C++ 语言中:
    • C++ 标准库中,没有 stdin 这样的标准输入流,而是使用 std::cinstd::out 来进行标准输入和标准输出。
    • 使用 <iostream.h> 头文件里的 getline() 函数或是 >><< 操作符。
  • 综上,在 C++ 中,输入输出流的使用通常是通过 iostream 库实现的,而在 C 中则是通过 stdio 库实现的。

文件输入输出流

  • 文件输入输出流则是将数据保存在磁盘上的文件中,通过打开和关闭文件,程序可以使用文件输入输出流进行数据的读取和写入。
  • C 语言中:
    • 文件输入输出流使用 C 标准库中的文件指针 FILE* 来实现。
    • 操作函数有 fopen(), fclose(), fread(), fwrite() 等。
  • C++ 语言中:
    • 文件输入输出流是基于 C 标准库中的文件操作函数封装而成,即 fstream 类。
    • 具体地,通过 std::ifstreamstd::ofstream 类实现,它们是 std::istreamstd::ostream 类的派生类。

相比标准输入输出流,文件输入输出流需要显式地指定要读写的文件,因此使用起来比较繁琐,但也更加灵活:文件输入输出流可以处理任何类型的文件,包括文本文件和二进制文件,而标准输入输出流只能处理字符流。此外,文件输入输出流可以通过随机访问文件的方式读写文件,而标准输入输出流只能顺序读写。


1.2 输入输出缓冲区


什么是输入输出缓冲区?

顾名思义,输入输出缓冲区就是输入输出缓冲的区域

C/C++ 中,输入输出缓冲区是用来存储输入输出数据的临时存储区域

  • 输入缓冲区是在数据流输入之前存储输入数据的临时存储区域。
  • 输出缓冲区是在数据流输出之前存储输出数据的临时存储区域。

说人话:输入输出缓冲区就是为了保存这些输入输出流而临时开辟出的一块内存


为什么要设置输入输出缓冲区?

众嗦粥汁,因为需要,所以设置

  • 缓冲区是在内存中,而外设则是在硬件中。
  • 相比于从硬件中读取和写入数据,从内存中读取和写入数据更加快速。

因此,当程序需要读取或写入大量数据时,使用缓冲区可以将这些数据先存储到内存中,然后再一次性地写入或读取,避免了频繁访问硬件的开销。此外,缓冲区还可以优化数据的排列和格式,以便更高效地读取和写入数据。

说人话:缓冲区的存在是为了提高输入输出效率,减少对外设的访问次数


C/C++ 的输入输出缓冲区有何不同?

别急别急别急

首先别急,其次别急,所以我们先来了解下:输入输出缓冲区的空间由什么来分配?开辟在哪里?何时开辟?这个问题:

  • 输入输出缓冲区的空间通常由操作系统来分配的;
  • 一般情况下,是在程序运行时从内存中分配的,在程序运行空间中分配的,不是在操作系统的内核空间中分配;
  • 分配的时机和分配的空间大小会根据具体的实现而不同,一般地,当程序通过输入输出函数向缓冲区写入或者读取数据时,缓冲区就会被分配。

具体地

  • 分配缓冲区的时机:
    • 对于标准输入输出流:缓冲区的空间通常是在程序启动时预先分配好的。
    • 对于文件输入输出流:缓冲区的空间是在文件流和流缓冲区对象创建时动态分配的,这些对象通常是在程序开始时被初始化的。
    • 缓冲区的大小通常是由实现细节所决定的,但是一般来说,缓冲区的大小应该足够容纳输入或输出数据的常规大小,同时又不能过大以致于浪费内存。
  • 分配缓冲区的大小:
    • 缓冲区的大小应该足够容纳输入或输出数据的常规大小,同时又不能过大以致于浪费内存
    • 由实现库来完成对缓冲区大小的分配,具体实现细节可能会因编译器或操作系统的不同而有所差异。
    • 一般来说,实现库会通过调用操作系统提供的系统调用或动态内存分配函数来分配缓冲区的空间。
    • 在内存空间紧张的情况下,缓冲区的大小可能会被限制,从而可能影响到程序的性能和可靠性。

急急急急急急

我知道你急了,但是你先别急,这部分其实不用太纠结。的。对吧:

  • C 语言中,标准输入输出库 <stdio.h> 提供了输入输出缓冲区的实现。
    • 主要使用了三个函数:setbuf()setvbuf()fflush()
    • 其中,setbuf()setvbuf() 可以用来设置缓冲区,而 fflush() 用来清空缓冲区并把缓冲区中的数据输出到文件。
    • 因此,C 中的输入输出函数,如 scanf()printf() 等,是非类型安全的
    • 它们依赖于格式化字符串来指示输入/输出数据的类型。
    • 如果格式化字符串不正确,就会导致不可预测的结果,如缓冲区溢出和未定义的行为。
  • C++ 中,<iostream> 库提供了输入输出缓冲区的实现。
    • 提供了两种不同的缓冲区:streambuffilebuf
    • streambuf<iostream> 库的基类,提供了对输入输出缓冲区的访问;而 filebuf<fstream> 库的基类,提供了对文件输入输出缓冲区的访问。
    • 但是,<iostream> 库还提供了一些类似 setbuf()setvbuf()flush() 等函数,用来管理输入输出缓冲区。在关闭同步流之后,<iostream> 库使用了一种不同于标准输入输出库的机制来提高效率,例如使用字符串流 stringstream 和缓冲流 buffer stream 等。
    • 因此,C++ 中的输入输出函数,如 std::cinstd::cout 等,是类型安全的
    • 它们使用类型安全的 C++ 流语义,其中数据类型是静态确定的,而不是动态确定的。
    • 这意味着数据类型在编译时就已经确定,而不是在运行时根据格式化字符串动态确定。
    • 这种静态类型检查可以在编译时检测到类型不匹配的错误,从而使 C++ 的输入输出更加类型安全。

这就是为什么,你仍然可以在 C++ 中使用 scanf()printf(),但是仍建议在 C++ 中使用 <iostream> 库所提供的标准输入输出的原因,以及为什么我们常说 C++C 更适于面向对象。

总结:这部分真的不用太纠结。中肯的。正确的。理智的。一针见血的。真的。


2. 谈谈输入输出的方式


2.1 C/C++ 的输入和输出


你急了,你急了,你急了,因为你很迷,你不明白 stdinscanfcinstd::cingetlinestringstream 还有 stdoutprintfcoutstd::cout 这些都是什么寄吧玩意,对吧?再来明确一下:

  • stdinC 语言中的标准输入流。
  • cinC++ 中的标准输入流,而 std::cinC++ 标准库命名空间中的标准输入流,cin 是使用命名空间 std 的缩写,即cinstd::cin 的别名。
  • scanf()C 语言中的输入函数,而 cinstd::cinC++ 中的输入流。scanf() 的参数需要使用格式化字符串来指定输入数据的类型,而 cinstd::cin 可以自动识别输入数据的类型。
  • getline()C++ 中的输入函数,可以用于从输入流中读取一行文本数据,可以指定分隔符。getline() 可以替代 scanf()cin 用于读取字符串类型数据。
  • stdoutC 语言中的标准输出流。
  • coutC++ 中的标准输出流,而 std::coutC++ 标准库命名空间中的标准输出流。它们之间的区别同 cinstd::cin
  • printf()C 语言中的输出函数,而 coutstd::coutC++ 中的输出流。printf() 的参数需要使用格式化字符串来指定输出数据的类型,而 coutstd::cout 可以自动识别输出数据的类型。
  • 至于 stringstream 这个东西,我们放到最后细嗦。

scanf() 和 printf()

因为我们对这两个东西再熟悉不过了,所以我们对这两个东西根本不陌生,这俩是 C 语言中的标准输入和标准输出函数。

对于 printf(),只需要注意下面几点:

  • 用法:scanf(format, argument_list);
  • 用于向控制台输出数据,可以输出多种类型的数据,如整数、浮点数、字符、字符串等。
  • 在输出字符串时,需要注意字符串中是否包含特殊字符,如换行符、制表符等,需要使用相应的转义字符来表示。
  • 可以使用格式化输出来控制输出的格式,如输出精度、对齐方式等。

而对于 scanf(),除了基本注意点:

  • 用法:scanf(format, argument_list);
  • 用于从控制台输入数据,可以读取多种类型的数据,如整数、浮点数、字符、字符串等。
  • scanf() 输入数据时要求数据格式与 format 字符串中指定的格式匹配,否则会产生错误。

还需要注意:scanf() 函数的缓冲区不会自动清空,因此需要使用fflush(stdin)语句清空缓冲区,以防止输入的数据被下一个输入函数接收,如果仅仅为了处理掉换行符 \n,可以使用 getchar() 读取,将换行符“吃掉”。

举个栗子

观察下列代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

int main(){
    int n;                  //声明 int 类型变量 n
    scanf("%d", &n);        //读入 int 类型变量 n
    printf("%d\n", n);      //输出 int 类型变量 n 并且换行
    char c = getchar();     //读入一个字符,并存储在 char 类型变量 c 中
    printf("%c", c);        //输出 char 类型变量 c
    printf("14\n");         //输出 14 并且换行
    return 0;
}

假设运行并且在控制台输入如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
114
5

理论上,我期望得到输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
114
514

但实际上,控制台哼哼哼啊啊啊输出了如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
114

14

甚至控制台根本就没有接收你后续输入的 5 这个字符。

在该例子中,scanf("%d", &n)会读取输入流中的数字 114,并将其存储在变量 n 中。但是,由于输入缓冲区中还有一个换行符 \ngetchar()函数会读取这个换行符,并存储在变量 c 中,导致产生了这样的结果。在缓冲区中的数据没有被自动清空,这就是为什么控制台根本没有鸟你后续输入的东西,并输出了不符合预期的内容。

那么继续观察如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

int main(){
    int n;                  //声明 int 类型变量 n
    scanf("%d", &n);        //读入 int 类型变量 n
    printf("%d\n", n);      //输出 int 类型变量 n 并且换行
    getchar();              //用 getchar() 吃掉缓冲区中的 '\n'
    char c = getchar();     //读入一个字符,并存储在 char 类型变量 c 中
    printf("%c", c);        //输出 char 类型变量 c
    printf("14\n");         //输出 14 并且换行
    return 0;
}

重新编译运行并在控制台输入如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
114
5

可以发现控制台哼哼哼啊啊啊输出了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
114
514

在该例子中,为了避免上述缓冲区没有清空的情况,我们在读取完数据后手动清空输入缓冲区,利用 getchar() 读取了缓冲区里的换行符 \n,使得后续的字符 5 被成功读入,最终输出了符合预期的内容。


cin 和 cout

cincoutC++ 的输入输出流,可以使用它们来实现控制台的输入输出操作。一般地,使用 cincout 时可以通过引入 using namespace std; 简化代码,但也可以不引入命名空间,使用完整限定名 std::cinstd::cout

由于 cincout 的输入输出会自动匹配对应数据类型,所以针对这两者的格式化输入输出并非此处讨论的重点,而在此处,我们需要提及其关于同步流(synchronized stream)的概念:

  • 同步流意味着在程序流中输出数据时,程序必须等到数据完全输出到设备上,然后才能继续执行后面的代码。
  • 同样,当程序尝试从输入设备读取数据时,程序会等待用户输入完整的数据,然后才能继续执行后面的代码。

虽然同步流可以确保输入输出的正确性,但是在一些场景下会影响程序的效率,特别是在大量数据输入输出的情况下。

这就是为什么,即使 C++ 宁愿舍弃 scanf()printf() 的高性能,也要得到输入输出流同步所带来的安全性和正确性,这也使得 C++ 更适合面向对象开发。


getchar() 和 getline()

把这两个放一起存粹是因为他们长得很像,但是两者天差地别:

  • getchar()函数从标准输入(stdin)中读取一个字符,返回该字符的 ASCII 码值。
  • 通常用于读取单个字符或者字符数组,可以实现简单的输入操作。
  • 使用时需要注意的是,由于输入的字符是直接通过键盘输入的,因此需要按下回车键才能将输入的字符送入缓冲区,此时getchar()才能够读取到输入的内容。
  • getline()函数从输入流中读取一行文本,并将其存储到一个字符串对象中,可以读取包含空格在内的一整行输入。
  • 使用时需要注意的是,如果使用默认的分隔符 \ngetline() 会将换行符读取到缓冲区,如果下一次使用 getline() 读取输入,就会导致缓冲区中的换行符被读取,而不是期望的输入。此时可以通过调用cin.ignore()来清除缓冲区中的字符,或者指定其他分隔符。

关于 getchar() 缓冲区的问题已经讲过,下面举个 getline() 的栗子:

观察下列代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>

using namespace std;

int main() {

    string s; 

    getline(cin, s);  //读入 string 类型 s

    cout << "First: " << s << endl;  //输出 s

    getline(cin, s);  //在此读入

    cout << "Second: " << s << endl;  //再次输出 s

    return 0;
}

假设运行并且在控制台输入如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
114
514

理论上,我期望得到输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
First: 114
Second: 514

但实际上,控制台哼哼哼啊啊啊输出了如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
First: 114
Second: 514

你会惊讶地发现符合期望,然后你想:“诶这不是没毛病垃圾 Lys 玩我呢?”

你先别急,让我先急。

getline() 其参数实际上有三个,第三个参数为分隔符参数,即 getline() 会以该参数分割处理数据,默认缺省该参数的情况下,getline() 会以 \n 为分隔符,即默认我们使用的是 getline(cin, s, '\n');

那么在该例子中,输入 114 后按下回车键,该回车键被视为一个分隔符并从输入流中删除,此时 \n 仍然留在缓冲区中 。然后第二个 getline() 调用会读取缓冲区中剩余的字符,即 "\n514",将其中的 \n 删除并存储 514。因此输出符合预期。

我们重新指定一下 getline() 的分隔符,修改得到如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>

using namespace std;

int main() {

    string s; 

    getline(cin, s, ',');  //读入 string 类型 s,并以 ',' 为分隔符

    cout << "First: " << s << endl;  //输出 s

    getline(cin, s, ',');  //在此读入

    cout << "Second: " << s << endl;  //再次输出 s,并以 ',' 为分隔符

    return 0;
}

假设运行并且在控制台输入如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
114,
514,

理论上,我期望得到输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
First: 114
Second: 514

但实际上,控制台哼哼哼啊啊啊输出了如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
First: 114
Second: 
514

你会惊讶地发现这次不符合期望了,然后你想:“诶这不废话吗垃圾 Lys 玩我呢?”

你急了,但是你先别急。

在该例子中,输入 114, 后按下回车键,',' 则被视为了一个分隔符并从输入流中删除,但后续输入的 \n 保留在了缓冲区中 。然后第二个 getline() 调用会读取缓冲区中剩余的字符,即 "\n514,",将其中的 ',' 删除并存储 \n514。因此输出了不符合预期的内容。

为了避免这种结果,我们同样需要手动清空缓存区,可以使用 getchar() “吃掉”缓冲区中的 \n,但更建议使用如下方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>

using namespace std;

int main() {

    string s; 

    getline(cin, s, ',');  //读入 string 类型 s

    cout << "First: " << s << endl;  //输出 s

    // 使用 cin.ignore() 忽略掉输入缓冲区中的换行符
    // 也可以使用 cin.get() 读取缓冲区中的换行符
    cin.ignore();
    // cin.get();

    getline(cin, s, ',');  //在此读入

    cout << "Second: " << s << endl;  //再次输出 s

    return 0;
}

最终得到了符合预期的结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
First: 114
Second: 514

总体而言,getchar()适用于读取单个字符或者字符数组,而getline()适用于读取一整行文本,两者使用时需要注意不同的输入方式和缓冲区处理


stringstream

  • stringstreamC++ 标准库提供的一种数据流对象,用于在内存中对字符串进行输入输出操作。
  • 它可以像 cincout 一样进行输入输出,并且具有和输入输出流相似的接口和方法,例如 <<>> 操作符。
  • 它提供了将一个字符串转换成一个数据类型的方法,方便程序员进行数据处理。
  • C++ 中,stringstream 也是类型安全的

stringstreamcincout 等输入输出流都有类似的接口和方法,可以进行输入输出操作,但它们的作用域不同。cincout 等输入输出流通常用于标准输入输出流,而 stringstream 通常用于字符串的处理。

通常我们可以使用 stringstream 对字符串进行分割、转换、拼接等操作,然后再使用 cincout 输出到标准输入输出流中:

  • 我们可以使用 getline() 函数从标准输入读取一行字符串;
  • 然后使用 stringstream 将其转换为数值类型,最后再使用 cout 输出到标准输出流中。
  • 这样的代码既可以处理标准输入输出流,又可以方便地进行字符串操作,提高了程序的可扩展性和复用性。

举个栗子

观察如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main() {
    stringstream s;
    string name = "Lys";
    int age = 13;
    double height = 1.86;
    string status = "is a dog";

    s << "Name: " << name << ", Age: " << age << ", Height: " << height << ", Status: " << status;
    string str = s.str();

    cout << str << endl;

    return 0;
}

在这个示例中,我们首先创建了一个 stringstream 对象 s,然后使用<<运算符将字符串、整数和浮点数和一个字符串插入到 s 中,最后使用 str() 方法将所有插入的数据转换为一个字符串,并将其打印到标准输出中。

再比如,观察如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main() {

    string s;
    getline(cin, s);

    stringstream ss(s);
    string str;

    while(ss >> str){
        cout << str << endl;
    }

    return 0;
}

编译运行并且在控制台输入如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Lys is a dog.

然后得到如下输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Lys
is
a
dog.

在这个示例中,我们首先创建了一个 string 类型的 s,并用 getline(cin, s) 读入字符串,然后将字符串 s 转换为了stringstream 对象 ss,再通过该对象过滤空格后不断赋值给 str,最终将其打印到标准输出中。


2.2 关闭 C++ 标准流同步


前面提到了,由于 cincout 的同步流机制,因此,在性能上, scanf()printf() 输入输出的效率显著优于 cincout,但我们仍然可以通过设置 cincout 的同步流标志位来关闭同步流,从而提高程序的效率,甚至优于 scanf()printf()

C++ 程序中,添加如下语句以优化输入输出流速度和交互性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ios::sync_with_stdio(false);
 cin.tie(nullptr);
 cout.tie(nullptr);
  • ios::sync_with_stdio(false):关闭 C++ 的标准输入输出流与 C 语言输入输出流的同步,从而加快输入输出的速度。
  • cin.tie(nullptr):解除 cincout 的绑定,从而避免在读取输入时,每次输出缓存区都被刷新的问题。
  • cout.tie(nullptr):解除 coutcin 的绑定,从而避免在输出时,每次读取输入都会刷新输出缓存区的问题。

需要注意的是,关闭输入输出流同步后,不能再在 C++ 代码中使用 C 语言的输入输出函数了,否则可能会导致输出不完整或者输出顺序错误等问题。此外,解除绑定后,需要手动刷新输出缓存区,否则输出的内容可能不完整或者不及时。因此,在使用这些语句时,需要谨慎地考虑使用场景和执行顺序,避免出现不可预料的错误。

下列语句:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ios::sync_with_stdio(false);
 cin.tie(0);
 cout.tie(0);

同样可以达到提高输入输出速度的目的。这种写法比使用 nullptr 更加通用,因为在某些旧的 C++ 编译器中可能不支持 nullptr

总的来说,这两种写法的区别并不大,只是在解除绑定时所使用的空指针常量不同,但都可以实现提高输入输出速度的效果。


3. 最后的练习


3.1 泛凯撒加密


Original Link

描述

众所周知,在网络安全中分为明文和密文,凯撒加密是将一篇明文中所有的英文字母都向后移动三位(Z 的下一位是 A),比如 a 向后移动三位就变成了 dA 向后移动三位就变成了 DZ 向后移动三位就变成了 C,但是泛凯撒加密可没有这么简单,它是将明文中的每个字母向后移动k位得到密文,并且在密文的结尾会附加一个 ?,本题想让你通过得到密文反解出原本的明文。

输入格式

第一行,输入一个正整数 k 表示字母向后移动的位数。

接下来输入若干行字符串,表示密文,数据输入保证仅密文的最后一个字符是 ?

输出格式

输出原本的明文。

数据范围

0k100


3.2 题解


你已经是一个成熟的  ACMer  了,要学会自己分析并解决问题。实在解决不了就解决自己吧。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <cstring>

using namespace std;

void solve(){
    int k; cin >> k;
    string s;
    k %= 26;
    getchar();  //清空缓冲区中的 '\n'
    while(getline(cin, s)){
        for(int i = 0; i < s.size(); i ++){
            char st = s[i];
            if(st >= 'a' && st <= 'z') cout << char(st - k < 'a' ? st - k + 26 : st - k);
            else if(st >= 'A' && st <= 'Z') cout << char(st - k < 'A' ? st - k + 26 : st - k);
            else if(st == '?') break;
            else cout << st;
        }
        cout << endl;
    }
}

int main(){
    solve();
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-2-26 2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
详解C/C++输入输出
C/C++输入输出很多,在不同的情况会用不同的输入输出,有的题目在输入时可能换一种输入输出就能不会TLE,有的输入可能要循环输入,但是可以换一种输入直接就能把所有数据输入进去。C/C++有哪些常用的输入输出,在什么时候用它们,这篇博客我会一一详解。
摆烂小白敲代码
2024/09/23
3080
详解C/C++输入输出
【C++学习】 IO 流揭秘:高效数据读写的最佳实践
🚀C++ IO 流(输入输出流)是一种用于处理数据流的机制,允许程序读取和写入数据。它包括
IsLand1314
2024/10/15
3400
【C++学习】 IO 流揭秘:高效数据读写的最佳实践
C++从入门到精通——C++输入和输出
C++中的输入和输出主要通过标准库中的iostream类实现。使用cin对象从标准输入(如键盘)读取数据,使用cout对象将数据写入标准输出(如屏幕)。
鲜于言悠
2024/03/30
1.1K0
C++从入门到精通——C++输入和输出
C++ 输入输出详解:从概念、原理到多种优化讲解
在C++中,输入和输出操作是通过流(stream)进行的。流是一个抽象接口,它允许程序从源(如键盘、文件、网络等)读取数据,或者向目标(如屏幕、文件、网络等)写入数据。
码事漫谈
2024/12/25
1750
C++ 输入输出详解:从概念、原理到多种优化讲解
【蓝桥杯C/C++】代码性能提升技巧:输入输出优化
在C++中,标准输入输出流 (cin 和 cout) 默认与C语言的标准输入输出 (scanf 和 printf) 是同步的。这种同步机制的目的是防止混用C风格和C++风格的输入输出时出现不一致。然而,这种同步会引入显著的性能开销。对于竞赛场景,我们通常优先考虑速度,因此禁用同步机制是必要的优化手段。
CSDN-Z
2024/11/21
3670
【蓝桥杯C/C++】代码性能提升技巧:输入输出优化
【C++课程学习】:C++中的IO流(istream,iostream,fstream,sstream)
https://blog.csdn.net/djdjiejsn/category_12682189.html
用户11396661
2025/01/20
1690
【C++课程学习】:C++中的IO流(istream,iostream,fstream,sstream)
【C++高阶】深入理解C++ I/O流:标准库中的隐藏宝石
前言:在编程的世界中,输入与输出(I/O)是连接程序与现实世界的桥梁。无论是从键盘接收用户指令,还是将处理结果输出到屏幕或文件,I/O操作都是程序设计中不可或缺的一部分。对于C++这一强大而灵活的编程语言而言,其丰富的I/O流库更是为开发者提供了高效、灵活且易于使用的数据交换机制
Eternity._
2024/09/24
1560
【C++高阶】深入理解C++ I/O流:标准库中的隐藏宝石
C++:32---IO库
一、IO库 I0库类型和头文件 头文件 类型 iostream istream,wistream从流读取数据ostream,wostream向流写入数据iostream,wiostream读写流
用户3479834
2021/02/03
5840
C++:32---IO库
【C++语言】 cin和cout的详解
cin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出流的对象,也是ostream 类的对象。这里的标准输出指的是终端键盘,标准错误输出指的是终端的屏幕。
编程范 源代码公司
2019/10/09
11.3K1
【C++语言】   cin和cout的详解
【C++】————IO流
C语言中我们用到的最频繁的输入输出方式就是 scanf() 和 printf()。
用户11036582
2024/09/12
920
【C++】————IO流
清除 C/C++ 中的输入缓冲区
什么是缓冲区? 临时存储区域称为缓冲区。所有标准输入和输出设备都包含一个输入和输出缓冲区。在标准 C/C++ 中,流被缓冲,例如在标准输入的情况下,当我们按下键盘上的键时,它不会发送到您的程序,而是由操作系统缓冲,直到时间分配给那个程序。
鲸落c
2023/05/23
1.1K0
十二、IO流
虽然C语言没有内置的IO流机制,但C++通过继承C语言的I/O库(如stdio.h中的函数)并扩展其功能,引入了IO流库。C++的IO流库提供了面向对象的接口,使得处理输入输出变得更加灵活和强大。
用户11332765
2024/10/28
810
C++ 中的基本输入\u002F输出
theme: channing-cyan highlight: a11y-dark
鲸落c
2022/11/14
9240
一文带你读懂C/C++语言输入输出流与缓存区
有没有发现,基本上所有的C语言入门书籍,或者是我们的教程里面,第一个C语言程序实体,都是“Hello Word!”;我不知道这是不是行业的“潜规则”,总之,它把无数的程序员带进了计算机的世界,步入了代码的大坑里,所以你好,世界!
李肖遥
2020/06/24
1.9K0
一文带你读懂C/C++语言输入输出流与缓存区
有没有发现,基本上所有的C语言入门书籍,或者是我们的教程里面,第一个C语言程序实体,都是“Hello Word!”;我不知道这是不是行业的“潜规则”,总之,它把无数的程序员带进了计算机的世界,步入了代码的大坑里,所以你好,世界!
李肖遥
2020/06/23
1.2K0
从零开始学C++之IO流类库(一):流类库继承体系(IO流,文件流,串流)和 字符串流的基本操作
s1mba
2017/12/28
1.8K0
从零开始学C++之IO流类库(一):流类库继承体系(IO流,文件流,串流)和 字符串流的基本操作
【C++掌中宝】玩转C++标准输入输出(简洁明了)
C++ 标准库提供了一组丰富的输入/输出功能,本章将讨论 C++ 编程中最基本和最常见的 I/O 操作——C++的标准输入输出。
Crossoads
2024/10/22
1700
【C++】std命名空间及输入输出流
上一篇的命名空间剩下的还有std(官方库的命名空间),用来串联这节的输入输出流;但是我还是要把他放在后面,“让子弹在飞一会”;
啊QQQQQ
2024/11/19
930
类型转换与IO流:C++世界的变形与交互之道
在现代编程中,C++作为一种强大的面向对象编程语言,其灵活性和高效性在开发中得到了广泛应用。类型转换和输入输出流(IO流)是C++语言的两个重要组成部分。前者是数据处理与操作的桥梁,后者是数据交互的核心。掌握这些内容不仅可以提高代码的健壮性,还能显著提升开发效率与代码可读性。本文将深入探讨C++中的类型转换和IO流机制,助您在实际应用中游刃有余。
suye
2024/12/20
1170
C++初阶-IO流
键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了;只有把输入缓冲区中的数据取完后,才要求输入新的数据
用户9645905
2022/11/30
1.4K0
C++初阶-IO流
推荐阅读
相关推荐
详解C/C++输入输出
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文