【C++】第7章 输入输出流

目录

7.1   流类

7.2   标准流对象

7.3   使用流操纵算子控制输出格式

7.4   调用 cout 的成员函数

7.5   cin 的高级用法

        7.5.1   判断输入结束

        7.5.2   istream 类的成员函数

        1. get

        2. getline

        3. eof

        4. ignore

        5. peek


7.1   流类

        程序中常用的cin和cout,分别用于从键盘输入数据和向屏幕输出数据(简称为标准 I/O)。除此之外,程序还可以从文件中读入数据,以及向文件中写入数据(简称为文件 I/O)。数据输入和输出的过程也是数据传输的过程,数据像水一样从一个地方流动到另一个地方,因此,在C++中将此过程称为 “流” 。在C++的标准类库中,将用于进行数据输入输出的类统称为 “流类” 。cin 是流类 istream 的对象,cout 是流类 ostream 的对象。要使用流类,需要在程序中包含 iostream 头文件。C++中常用的几个流类及其相互关系如图7.1所示。

         图7.1中的箭头代表派生关系。例如,ios 是抽象的基类,它派生出 istream 和 ostream 。istream 和 ostream 又同时派生了 iostream 类。为了避免多继承的二义性,从 ios 派生出 istream 和 ostream 时,均使用了 virtual 关键字。

        istream 是用于输入的流类,cin 就是该类的对象。

        ostream 是用于输出的流类,cout 就是该类的对象。

        ifstream 是用于从文件读取数据的类。

        ofstream 是用于向文件写入数据的类。

        iostream 是既能用于输入,又能用于输出的类。

        fstream 是既能从文件读取数据,又能向文件写入数据的类。

7.2   标准流对象

        iostream 头文件中定义了四个标准流对象:cin、cout、cerr 和 clog。

        cin 对应于标准输入流,用于从键盘读取数据,也可以被重定向为从文件中读取数据。

        cout 对应于标准输出流,用于向屏幕输出数据,也可以被重定向为从文件中读取数据。

        cerr 对应于标准错误输出流,用于向屏幕输出出错信息,不能被重定向。

        clog 对应于标准错误输出流,用于向屏幕输出出错信息,不能被重定向。

        cerr 和 clog 的区别在于:cerr 不使用缓冲区,直接向显示器输出信息;而输出到 clog 中的信息会先存放到缓冲区,缓冲区满或者刷新时才输出到屏幕。

        cout 是 ostream 类的对象,定义如下:

                _PURE_APPDOMAIN_GLOBAL static filebuf fout(_cpp_stdout);

                _PURE_APPDOMAIN_GLOBAL extern_CRTDATA2 ostream cout(&fout);

        简单的看,就是:

                ostream cout(&fout);

        ostream 类的无参构造函数和复制构造函数都是私有的,因此在程序中一般无法定义 ostream 类的对象,唯一能用的 ostream 类的对象就是 cout。当然,上面关于 cout 对象的定义语句说明 ostream 类还是有一个公有构造函数的,如果知道这个构造函数是什么样的,那么也能自己定义 ostream 类的对象——但这么做并无必要。

        cout 可以被重定向,而 cerr 不能。所谓重定向,就是将输入的源或输出的目的地改变。例如,cout 本来是输出到屏幕上的,但是经过重定向,本该输出到屏幕上的东西就可以被输出到文件中。例如下面的程序:

#include <iostream>
using namespace std;
int main()
{
    int x,y;
    cin >> x >> y;
    freopen("test.txt","w",stdout);  //将标准输出重定向到 test.txt文件
    if( y == 0 )  //除数为0则输出错误信息
    		cerr << "error." << endl;
    else
	    cout << x /y ;
 	return 0;
}

        第7行的 freopen 是一个标准库函数,第二个参数 w 代表写模式,第三个参数代表标准输出。该语句的作用是将标准输出重定向为 test.txt 文件中。重定向之后,所有对 cout 的输出都不再出现在屏幕上,而是出现在 test.txt 文件中。test.txt 文件会和本程序的可执行文件出现在同一个文件夹中(目前测试下来,需要自建 test.txt)。重定向仅对本程序有效,不影响其他程序。运行本程序,输入
                6(空格)2(回车)

程序没有输出,但是打开 test.txt 文件,可以看到文件中有

                3

输入

                4(空格)0(回车)

则程序屏幕上输出

                error.

说明cerr不会被重定向。

        cin 也是可以被重定向的。如果在程序中加入

                freopen("input. dat", "r", stdin);

第二个参数 r 代表读入方式,第三个参数 stdin 代表标准输入。执行此语句后,cin 就不再从键盘读入数据,而是从 input. dat 文件中读入数据,input. dat 文件中有什么,就相当于从键盘输入了什么。

7.3   使用流操纵算子控制输出格式

        有时希望按照一定的格式进行输出,如按十六进制输出整数,输出浮点数时保留小数点后面两位,输出整数时按6个数字的宽度输出,宽度不足时左边补0,等等。在C++中,用 cout 进行输出时,可以通过流操纵算子进行格式控制。

        C++中常用的输出流操纵算子(也叫格式控制符)如表7.1所示。它们都是在头文件 iomanip中定义的。要使用这些流操纵算子,必须包含该头文件。

表7.1 C++流操纵算子
流操纵算子作用
*dec        以十进制形式输出整数常用
hex        以十六进制形式输出整数
oct        以八进制形式输出整数
fixed        以普通小数形式输出浮点数
scientific        以科学计数法形式输出浮点数
left        左对齐,即在宽度不足时将填充字符添加到右边
*right        右对齐,即在宽度不足时将填充字符添加到左边
setbase (b)        设置输出整数时的进制,b = 8、10或16
setw (w)        指定输出宽度为w个字符,或输入字符串时读入w个字符
setfill (c)        在指定输出宽度的情况下,输出的宽度不足时用字符c填充(默认情况是用空格填充)
setprecision (n)        设置输出浮点数的精度为n。在使用非 fixed 且非 scientific 方式输出的情况下,n即为有效数字最多的位数,如果有效数字位数超过n,则小数部分四舍五入,或自动变为科学计数法输出并保留一共n位有效数字;在使用 fixed 方式和 scientific 方式输出的情况下,n是小数点后面应保留的位数。
setiosflags (标志)        将某个输出格式标志置为1
resetioflags (标志)        将某个输出格式标志置为0
boolapha        把 true 和 false 输出为字符串不常用
*noboolalpha        把 true 和 false 输出为0、1
showbase        输出表示数值的进制的前缀
*noshowbase        不输出表示数值的进制的前缀
showpoint        总是输出小数点
*noshowpoint        只有当小数部分存在时才显示小数点
showpos        在非负数值中显示+
*noshowpos        在非负数值中不显示+
*skipws        输入时跳过空白字符
noskipws        输入时不跳过空白字符
uppercase        十六进制数中使用 ‘A’ ~ ‘E’ 。若输出前缀,则前缀输出 “0X”,科学计数法中输出 ‘E’
*nouppercase        十六进制数中使用 ‘a’ ~ ‘e’ 。若输出前缀,则前缀输出 “0x”,科学计数法中输出 ‘e’
internal        数值的符号(正负号)在指定宽度内左对齐,数值右对齐,中间由填充字符填充

        表7.1中,“流操纵算子” 栏中的星号 “*” 不是算子的一部分,星号表示在没有使用任何算子的情况下,就等效于使用了该算子。例如,在默认情况下,整数是用十进制形式输出的,等效于使用了 dec 算子。

        使用这些算子的方法是将算子用 “<<” 和 cout 连用。例如:

                cout << hex << 12 << "," << 24;

        这条语句的作用是指定以十六进制形式输出后面两个数,因此输出结果是:

                c,18

        setiosflags 算子实际上是一个库函数,它以一些标志作为参数,这些标志可以是在 iostream 头文件中定义的以下几种取值,它们的含义和同名算子一样。

ios::leftios::rightios::internal
ios::showbaseios::showpointios::uppercase
ios::showposios::scientificios::fixed

        这些标志实际上都是仅有某比特位为1,而其他比特位都是0的整数。

        多个标志可以用 “|” 运算符连接,表示同时设置。例如:

                cout << setiosflags(ios::scientific|ios::showpos) << 12.34;

        输出结果是:

                +1.234000e + 001

        如果两个互相矛盾的标志同时被设置,如先设置 setiosflags(ios::fixed),然后又设置 setiosflags(ios::scientific),那么结果可能就是两个标志都不起作用。因此,在设置了某标志,又要设置其他与之矛盾的标志时,就应该用 resetiosflags 清楚原先的标志。例如下面三条语句:

                cout << setiosflags(ios::fixed) << 12.34 << endl;

                cout << resetiosflags(ios::fixed) << setiosflags(ios::scientific | ios::showpos)

                        << 12.34 << endl;

                cout << resetiosflags(ios::showpos) << 12.34 << endl;//清除要输出正号的标志

        输出结果是:

                12.340000

                +1.234000e + 001

                1.234000e + 001

        关于流操纵算子的使用,来看下面的程序。

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
	int n = 141;
	//1)别以十六进制、十进制、八进制先后输出n
	cout << "1) " << hex << n << " " << dec << n << " " << oct << n << endl;
	double x = 1234567.89, y = 12.34567;
	//2)保留5位有效数字
	cout << "2) " << setprecision(5) << x << " " << y << endl;
	//3)保留小数点后面5位
	cout << "3) " << fixed << setprecision(5) << x << " " << y << endl;
	//4)科学计数法输出,且保留小数点后面5位
	cout << "4) " << scientific << setprecision(5) << x << " " << y << endl;
	//5)非负数显示正号,输出宽度为12字符,宽度不足则用'*'填补
	cout << "5) " << showpos << fixed << setw(12) << setfill('*') << 12.1 << endl;
	//6)非负数不显示正号,输出宽度为12字符,宽度不足则右边用填充字符填充
	cout << "6) " << noshowpos << setw(12) << left << 12.1 << endl;
	//7)输出宽度为12字符,宽度不足则左边用填充字符填充
	cout << "7) " << setw(12) << right << 12.1 << endl;
	//8)宽度不足时,负号和数值分列左右,中间用填充字符填充
	cout << "8) " << setw(12) << internal << -12.1 << endl;
	cout << "9) " << 12.1 << endl;
	return 0;
}

        程序的输出结果是:

                1) 8d 141 215

                2) 1.2346e+006 12.346

                3) 1234567.89000 12.34567

                4) 1.23457e+006 1.23457e+001

                5) ***+12.10000

                6) 12.10000****

                7) ****12.10000

                8) -***12.10000

                9) 12.10000

        需要注意的是,setw 算子所起的作用是一次性的,即只影响下一次输出。每次需要指定输出宽度时都要使用 setw。因此可以看到,第9)行的输出因为没有使用setw,输出的宽度就不再是前面指定的12个字符。

        在读入字符串时,setw还能影响 cin 的行为。例如下面的程序:

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
	string s1,s2;
	cin >> setw(4) >> s1 >> setw(3) >> s2;
	cout << s1 << "," << s2 << endl;
	return 0;
}

        输入:

                1234567890(回车)

        程序的输出结果是:

                1234,567

        说明 “setw(4)” 使得读入 s1 时,只读入4个字符,其后的 “setw(3)” 使得读入 s2 时只读入3个字符。

        setw 用于 cin 时,同样只影响下一次的输入。

7.4   调用 cout 的成员函数

        ostream 类有一些成员函数,通过 cout 调用它们也能用于控制输出格式,其作用和流操纵算子相同,如表7.2所示。

表7.2 ostream 类的成员函数
成 员 函 数作用相同的流操纵算子
precision(n)setprecision(n)
width(w)setw(w)
fill(c)setfill(c)
setf(标志)setiosflags(标志)
unsetf(标志)resetiosflags(标志)

        setf 和 unsetf 函数用到的 “标志” ,与 setiosflags 和 resetiosflags 用到的完全相同。

        这些成员函数的用法十分简单。例如下面的三行程序:

                cout.setf(ios::scientfic);

                cout.precision(8);

                cout << 12.23 << endl;

输出结果是:

                1.22300000e + 001

        cout 有一个成员函数 put,可以用来输出一个字符。其参数类型为 int,代表要输出的字符的 ASCII 码,其返回值是 cout 的引用。例如下面的两条语句:

                cout.put('a');

                cout.put(98).put('c').put('z');

输出结果是:

                abcz

        98是 'b' 的 ASCII 码,'a' 和 'z' 都能自动转换成证书,即字符对应的 ASCII 码。

        ostream 类还有以下成员函数:put 函数、write 函数、flush 函数、tellp 函数、seekp 函数。由于关于 cout 的大部分操作可以用流操纵算子完成,故这里不做详解,具体可参考:

c++中ostream类的超详细说明_c++ ostream_cpp加油站的博客-CSDN博客

7.5   cin 的高级用法

        7.5.1   判断输入结束

        cin 可以用来从键盘输入数据;将标准输入重定向为文件后,cin 也可以用来从文件中读入数据。在输入数据的多少不确定,且没有结束标志的情况下,该如何判断输入数据已经读完了呢?例如,输入若干个正整数,输出其中的最大值,程序该如何编写?代码如下:

#include <iostream>
using namespace std;
int main()
{
	int n;
	int maxN = 0;
	while(cin >> n){	//输入没有结束,条件就为真
		if(maxN < n)
			maxN = n;
	}
	cout << maxN;
	return 0;
}

        假设该程序编译得到的可执行程序是 mycin.exe。在Windows 系统中,通过键盘输入时,在单独的一行按 Ctrl+Z 键后再按回车键就代表输入结束。因此程序运行时,输入若干个正整数后换行,再按 Ctrl+Z 键和回车键,程序就会输出最大值并结束。即 “cin >> n” 这个表达式在碰到 Ctrl+Z时,会返回 false。在 UNIX/Linux 系统中,Ctrl+D 代表输入结束。

        如果将标准输入重定向为某个文件,如在程序开始添加 “freopen("test.txt", "r", stdin);” 语句,或者不添加上述语句,但是在 Windows 的 “命令提示符” 窗口输入:

                mycin < test. txt

则都能使得本程序不再从键盘输入数据,而是从 test. txt 文件输入数据(前提是 test. txt 文件和 mycin. exe 在同一个文件夹中)。在这种情况下,test. txt文件中并不需要包含 Ctrl+Z,只要有用空格或回车隔开若干个正整数即可。cin 读到文件末尾时,“cin > n” 就会返回 false 而导致程序结束。例如,嘉定 test .txt 文件中的内容如下所示:

                112

                23123

                34 444 55

                44

        则程序的输出是;

                23123

        在第4章 “运算符重载” 中提到过 istream 类将 “ >>” 重载为成员函数,而且这些成员函数的返回值是 cin 的引用。准确地说,“cin >> n” 的返回值的确是 istream & 类型的,而 while 语句中的条件表达式的返回值应该是 bool 类型、整数类型或其他和整数类型兼容的类型,istream & 显然和整数类型不兼容,为什么 “while(cin >> n)” 还能成立呢?这是因为,istream 类对强制类型转换运算符bool进行了重载,这使得 cin 对象可以被自动转换成 bool 类型。所谓自动转换的过程,就是调用 cin 的 operator bool 这个成员函数,而该成员函数可以返回某个标志值,该标志值在 cin 没有读到输入结尾时为 true,读到输入结尾后变为 false。对该标志值的设置,在 operator << 成员函数中进行。

        如果 cin 在读取过程中发生了错误,“cin >> n” 这样的表达式也会返回 false。例如下面的程序:

#include <iostream>
using namespace std;
int main()
{
    int n;
    while(cin >> n)
        cout << n << endl;
    return 0;
}

        程序本该输入整数,如果输入了一个字母,则程序就会结束。因为,应该读入整数时却读入了字母也算读入出错。

        7.5.2   istream 类的成员函数

        istream 类有一些成员函数,这里介绍最常用的几个。

        1. get

        istream 类有多个名为 get 的成员函数,这里只介绍其中的一个。其原型是:

                int get();

        此函数从输入流中读入一个字符,返回值就是该字符的 ASCII码。如果碰到输入的末尾,则返回值为 EOF。EOF 是 End of File 的缩写。istream 类中从输入流(包括文件)中读取数据的成员函数,在把输入数据都读取完后再进行读取,就会返回 EOF。EOF 是在 iostream中定义的一个整型常量,值为-1;

        get 函数不会跳过空格、制表符、回车等特殊字符,所有的字符都能被读入。例如下面的程序:

#include <iostream>
using namespace std;
int main()
{
    int c;
    while((c = cin.get()) != EOF)
        cout.put(c);
    return 0;
}

        程序运行情况如下:

                输入:

                Hello world!(回车)

                输出:

                Hello world!(回车)

                再输入:

                ^Z(回车)

                输入^Z(回车)后程序结束。

        程序中的变量 c 应为 int 类型,而不能是 char 型。在输入流中碰到 ASCII码等于 0xFF 的字符时,cin.get() 返回 0xFF,0xFF 赋值给 c,此时如果 c 是 char 类型的,那么其值就是 -1(因为符号位为1代表负数),即等于 EOF,于是程序就错误的认为输入已经结束。而在 c 为 int 类型的情况下,将 0xFF 赋值给 c,c 的值就是255(因为符号位为0,是正数),而非-1,即除非读到输入末尾,c 的值都不可能是-1.

        要将文本文件 test.txt 中的全部内容原样显示出来,程序可以如下编写:

#include <iostream>
using namespace std;
int main()
{
    int c;
    freopen("test.txt", "r", stdin);
    while((c = cin.get()) != EOF)
        cout.put(c);
    return 0;
}

        2. getline

        getline 成员函数有如下两个版本:

                istream & getline(char* buf, int bufSize);

                istream & getline(char* buf, int bufSize, char delim);

        第一个版本从输入流中读取 bufSize-1 个字符到缓冲区 buf,或读到 “\n” 为止(哪个条件先满足就按哪个执行)。函数会自动在 buf 中读入数据的结尾添加 “\0”。第二个版本和第一个版本的区别在于,第一个版本是读到 “\n” 为止,第二个版本是读到 delim 字符为止。“\n” 和 delim 都不会被读入 buf,但会被从输入流中取走。这两个函数的返回值就是函数所作用的对象的引用。如果输入流中 “\n” 或 delim 之前的字符个数达到或超过 bufSize,就会导致读入出错,其结果是:虽然本次读入已经完成,但是之后的读入都会失败。

        从输入流中读入一行,可以用第一个版本。用 cin >> s(假设 s 是 string 对象或 char* 指针)则不行,因为此种读法在碰到行中的空格或制表符时就会停止,因此就不能保证 s 中读入的是整行。第一个版本的 getline 函数的用法示例如下:

#include <iostream>
using namespace std;
int main()
{
	char szBuf[20];
	int n = 120;
	if(!cin.getline(szBuf,6))  //如果输入流中一行字符超过5个,就会出错
	    cout << "error" << endl;
	cout << szBuf << endl;
	cin >> n;	
	cout << n  << endl;;
	cin.clear(); //clear能够清除cin内部的错误标记,使之恢复正常
	cin >> n;
	cout << n << endl;
	return 0;
}

        程序的运行过程如下:

                ab cd(回车)

                ab cd

                33(回车)

                33

                44(回车)

                44

        在上面的输入情况下,程序是正常的。程序运行过程中还可能出现如下情况:

                ab cd123456k(回车)

                error

                ab cd

                120

                123456

        第7行,读入时因字符串超长导致出错,于是第11行并没有从输入流读入 n,n 维持原来的值120。第12行,调用 istream 的成员函数 clear 清除 cin 内部的错误标记,此后 cin 又能正常读入了。因此,123456在第13行被读入 n。

        可以用 getline 函数的返回值(为 false 则输入结束)来判断输入是否结束。例如,要将文件 test.txt 中的全部内容(假设文件中一行最长有10 000个字符)原样显示,程序可以如下编写:

#include <iostream>
using namespace std;
const int MAX_LINE_LEN = 10000;
int main()
{
    char szBuf[MAX_LINE_LEN+10];
    freopen("test.txt", "r", stdin);
    while(cin.getline(szBuf, MAX_LINE_LEN+5))
        cout << szBuf << endl;
    return 0;
}

        程序每次读入文件中的一行到 szBuf 并输出。szBuf 中不会读入回车符,因此输出 szBuf 后要在输出 endl 以换行。

        3. eof

                bool eof();

        此函数用于判断输入流是否已经结束。返回值为 true 表示输入结束。

        4. ignore

                istream & ignore(int n = 1, int delim = EOF);

        此函数的作用是跳过输入流中的 n 个字符,或跳过 delim 及其之前的所有字符,哪个条件先满足就按哪个执行。两个参数都有默认值,因此  cin.ignore() 就等效于 cin.ignore(1, EOF),即跳过一个字符。该函数常用于跳过输入中的无用部分,以便提取有用的部分。例如,输入的电话号码形式是 “Tel:63652823”,“Tel:” 就是无用的内容。例如下面的程序:

#include <iostream>
using namespace std;
int main()
{
    int n;
    cin.ignore(5, 'A');
    cin >> n;
    cout << n;
    return 0;
}

        程序的运行过程可能如下:

                abcde34(回车)

                34

        cin.ignore() 跳过了输入中的前5个字符,其余内容被当做整数输入 n 中。

        该程序的运行过程也可能如下:

                abA34(回车)

                34

        cin.ignore() 跳过了输入中的 'A' 及其前面的字符,其余内容被当做整数输入 n 中。

        5. peek

                int peek();

        此函数返回输入流中的下一个字符,但是并不将该字符从输入流中取走——相当于只是看了一眼下一个字符,因此叫 peek。cin.peek() 不会跳过输入流中的空格、回车符。在输入流已经结束的情况下,cin.peek() 返回 EOF。

        在输入数据的格式不同,需要预先判断格式再决定如何输入时,peek 就能起到作用。

        例题:编写一个日期格式转换程序,输入若干个日期,每行一个,要求全部转换为 “mm-dd- yyyy” 格式输出。输入的日期格式可以是 “2011.12.24”(中式格式),也可以是 “Dec 24 2011”(西式格式)。要求该程序对于以下输入数据:

                Dec 3 1990

                2011.2.3

                458.12.1

                Nov 4 1998

                Feb 12 2011

        输出结果应为:

                12-03-1990

                02-03-2011

                12-01-0458

                11-04-1998

                02-12-2011

        输入数据中的 Ctrl+Z 略去不写,因为输入数据也可能来自于文件。

        编写这个程序时,如果输入的是中式格式,就用 cin >> year(假设 year 是 int 类型变量)读取年份,然后再读取后面的内容;如果输入是西式格式,就用 cin >> sMonth(假设 sMonth 是 string 类型对象)读取月份,然后读取后面的内容。可是,如果没有将数据从输入流中读取出来,就无法判断输入到底是哪种格式。即便用 cin.get() 读取一个字符后再做判断,也很不方便。例如,在输入为 “2011.12.24” 的情况下,读取第一个字符 ‘2’ 后就知道是格式一,问题是输入流中的 ‘2’ 已经被读取了,剩下的表示年份的部分只有 “011”,如何将这个 “011” 和前面读取的 ‘2’ 凑成一个整数2011,也是颇费周折的事情。使用 peek 函数很容易解决这个问题。示例程序如下:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
string Months[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
	   			  	  "Sep","Oct","Nov","Dec" };
int main()
{
	int c;
	while((c = cin.peek()) != EOF) { //取输入流中的第一个字符进行查看
	 	int year,month,day;
	 	if(c >= 'A' && c <= 'Z') { //美国日期格式
			string sMonth;
			cin >> sMonth >> day >> year;
			for(int i = 0;i < 12; ++i)  //查找月份
		  	 	if(sMonth == Months[i]) {
					month = i + 1;
					break;
				}
		}
		else { //中国日期格式
			cin >> year ;
			cin.ignore() >> month ; //用ignore跳过 "2011.12.3"中的'.'
			cin.ignore() >> day;
		}
		cin.ignore();   //跳过行末 '\n'
		cout<< setfill('0') << setw(2) << month ;//设置填充字符'\0',输出宽度2
		cout << "-" << setw(2) << day << "-" << setw(4) << year << endl;
	}
	return 0;
}

        istream 还有一个成员函数 istream & putback(char c) ,可以将一个字符插入输入流的最前面。对于上面的例题,也可以用 get 函数读取一个字符并判断是中式格式还是西式格式时,将刚刚读取的字符再用 putback 成员函数放回流中,然后再根据判断结果进行不同方式的读入。

        注:istream 类还有以下成员函数:read 和 readsome 函数、putback函数、unget函数、sync函数、tellg 和 seekg函数。由于使用不是很常见,故不做详解,具体可以参考:

c++中istream类的超详细说明_cpp加油站的博客-CSDN博客

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值