C++中的IO类(输入和输出)

(一)输入输出

  • 程序的输入:从输入文件将数据传送给程序
  • 程序的输出:从程序将数据传送给输出文件

        C++的输入主要包括:对系统指定标准设备的输入输出(如从键盘输入,从显示器输出);以外存(磁盘、光盘等)为对象进行输入输出;对内存中指定空间进行输入输出。

(二)输入输出流

        输入和输出是数据传输的过程被称为流。流表示了信息从源到目的端的流动,有序连续,具有方向性。

        实际上,在内存中为每个数据流开辟一个内存缓冲区,用来存放流中的数据,即缓冲区中的数据就是流

        C++中,输入输出流被定义为类;I/O库中的类称为流类;用流类定义的对象称为流对象

(三)IO类

        不同种类的IO处理操作主要定义在三个独立的头文件中:iostream定义了用于读写流的基本类型,fstream定义了读写命名文件的类型,sstream定义了读写内存string对象的类型。

 头文件         类型
iostream       istream,wistream从流读取数据
               ostream,wostream从流写入数据
               iostream,wiostream读写流

fstream        ifstream,wifstream从文件读取数据
               ofstream,wofstream向文件写入数据
               fstream,wfstream读写文件

sstream        istringstream,wistringstream从string读取数据
               ostringstream,wostringstream向string写入数据
               stringstream,wstringstream读写string

        为了支持使用宽字符的,标准库定义了一组类型和对象来操纵wchar_t类型的数据,宽字符版本的类型和函数的名字以一个w开始。

(1)C++标准IO流 

对象含义对应设备有无缓冲区
cin标准输入流键盘有缓冲区
cout标准输出流键盘有缓冲区
cerr标准错误流屏幕无缓冲区
clog标准错误流屏幕有缓冲区

  • cin为缓冲流,键盘输入的数据保存在缓冲区,当需要提取时,从缓冲区提取;遇到Enter键完成输入;
  • //敲回车键的有
    int a;
    cin >> a;
    
    char c;
    c = getchar();
    
    int b;
    scanf("%d", &b);
    
    //末尾会添加一个空字符,如果键入1234567890会中断
    //只能键入123456789
    char str[10];  
    gets(str, 10);
  • 输入数据类型和要提取数据类型一致
  • cin和cout可以直接输入和输出内置类型数据 
  • 对于自定义的类型,如果要支持cin和cout的标准输入输出,需要对<<和>>进行重载

(2)IO对象无拷贝或赋值

        由于不能拷贝IO对象,因此我们不能将形参活返回类型设置为流类型,进行IO操作的函数通常以引用方式传递和返回流,读写一个IO对象会改变其状态,因此其引用不能是const的。

ofstream out1, out2; 
out1 = out2;  //错误,不能对流对象赋值
ofstream print(ofstream);  //错误,不能初始化ofstream参数
out2 = print(out2);   //错误,不能拷贝流对象

(3)条件状态

        IO操作一个与生俱来的问题就是可能发生错误,一些错误是可恢复的,而一些错误是发生在系统深处,已经超出应用程序可以修正的范围,而IO类所定义的一些函数和标志,可以帮助我们访问和操纵流的条件状态

        下面是一个错误的例子:

int val;
cin >> val;

        如果我们在标准输入上键入Boo,该操作就会失败,因为代码中输入运算符期待读取一个int,但却得到了一个字符B。

        一旦一个流发生了错误,其上后续的IO操作都会失败,只有当一个流处于无错误状态,我们才可以从它读取数据。确定一个流对象的状态最简单的方法就是将它当作一个流来使用:

while(cin >> word)
    //ok:读操作成功......

(四)C++文件IO流

暂补充

(五)C++ stringstream

  • 将整型变量的数据转换为字符串格式:(1)使用itoa()函数(2)使用sprintf()函数,但是使用时都得需要先给出保存结果的空间,而且转换格式需要匹配
	int n = 123456789;
	char s1[32];
	_itoa(n, s1, 10);
	cout << s1 << endl;  //123456789

	char s2[32];
	sprintf(s2, "%d", n);
	cout << s2 << endl;  //123456789

	char s3[32];
	sprintf(s3, "%f", n);
	cout << s3 << endl;   //0.000000

	char s4[32];
	float n1 = 3.2;
	sprintf(s4, "%f", n1);
	cout << s4 << endl;  //3.200000
  • 在C++中,可以使用stringstream类对象避开此问题,避免缓冲区溢出的危险,而且会对参数类型进行推演,不需要格式化控制,使用更安全。stringstream实际时在其底层维护了一个string类型的对象来保存结果
  • 多次数据类型转换时,一定要用clear(),才能正确转换,但clear()不会将stringstream底层的string对象清空
	int a = 123456;
	stringstream ss;   //字符串读写流
	string str;
	ss << a;    //a->ss
	ss >> str;   //ss->str
	cout << str << endl;   //输出123456

	ss.clear();  //清空ss
	float f = 1.2;
	ss << f;
	ss >> str;
	cout << str << endl;   //输出1.2
  • stringstream可以完成字符串拼接,可以使用s.str("")方法将底层string对象设置为""空字符串,可以使用s.str()让stringstream返回其底层的string对象
	stringstream ss;
	//把多个字符串放入stringstream
	ss << "first" << " " << "string,";
	ss << " second string";
	cout << ss.str() << endl;  //输出first string, second string

	//clear() 操作,并不会清除底层string对象
	ss.clear();
	cout << ss.str() << endl;  //输出first string, second string

	//删除底层,使用s.str("");
	ss.str("");
	ss << "third string";
	cout << ss.str() << endl;   //输出third string

补充一下:

(六)string 与 char* 和char[]的相互转换

(1)string 转换为 char*和char[]

  • 使用data()方法
	string str = "fisrt str";
	const char* p1 = str.data();
	cout << p1 << endl;   //输出fisrt str	
  • 使用c_str()方法
    string str = "fisrt str";
	const char* p1 = str.c_str();
	cout << p1 << endl;   //输出fisrt str
  • 使用copy()方法
	string str = "fisrt str";
	int len = str.length();
	char* p = new char[len + 1];
	str.copy(p, len, 0);  //第二个参数表示复制几个字符,第三个参数表示赋值的起始位置
	*(p + len) = '\0';   //一定要加上
	cout << p << endl;   //输出fisrt str

(2)char[] 转换为string

        多种方法,这里记录两种

  • 向构造函数传入c字符串创建string对象
  • 使用拷贝构造函数创建string对象
	char c[] = "hello world";
	//构造函数
	string str(c);
	//拷贝构造函数
	string str = c;

(七)string 转换为整数

	string k = "12345";
	cout << atoi(k.data()) << endl;
	cout << atoi(k.c_str()) << endl;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值