C++输入输出包含以下三个方面的内容:
对系统指定的标准设备的输入和输出。即从键盘输入数据,输出到显示器屏幕。这种输入输出称为标准的输入输出,简称标准I/O。
以外存磁盘文件为对象进行输入和输出,即从磁盘文件输入数据,数据输出到磁盘文件。以外存文件为对象的输入输出称为文件的输入输出,简称文件I/O。
对内存中指定的空间进行输入和输出。通常指定一个字符数组作为存储空间(实际上可以利用该空间存储任何信息)。这种输入和输出称为字符串输入输出,简称串I/O。
与iostream类库有关的头文件
iostream类库中不同的类的声明被放在不同的头文件中,用户在自己的程序中用#include命令包含了有关的头文件就相当于在本程序中声明了所需要用到的类。可以换 —种说法:头文件是程序与类库的接口,iostream类库的接口分别由不同的头文件来实现。常用的有
· iostream 包含了对输入输出流进行操作所需的基本信息。
· fstream 用于用户管理的文件的I/O操作。
· strstream 用于字符串流I/O。
· stdiostream 用于混合使用C和C + +的I/O机制时,例如想将C程序转变为C++程序。
· iomanip 在使用格式化I/O时应包含此头文件。
在iostream头文件中定义的流对象
在 iostream 头文件中定义的类有 ios,istream,ostream,iostream,istream 等。
在iostream头文件中不仅定义了有关的类,还定义了4种流对象,
对象 | 含义 | 对应设备 | 对应的类 | c语言中相应的标准文件 |
cin | 标准输入流 | 键盘 | istream_withassign | stdin |
cout | 标准输出流 | 屏幕 | ostream_withassign | stdout |
cerr | 标准错误流 | 屏幕 | ostream_withassign | stderr |
clog | 标准错误流 | 屏幕 | ostream_withassign | stderr |
在iostream头文件中定义以上4个流对象用以下的形式(以cout为例):
ostream cout ( stdout);
在定义cout为ostream流类对象时,把标准输出设备stdout作为参数,这样它就与标准输出设备(显示器)联系起来,如果有
cout <<3;
就会在显示器的屏幕上输出3。
在iostream头文件中重载运算符
“<<”和“>>”本来在C++中是被定义为左位移运算符和右位移运算符的,由于在iostream头文件中对它们进行了重载, 使它们能用作标准类型数据的输入和输出运算符。所以,在用它们的程序中必须用#include命令把iostream包含到程序中。
#include <iostream>
1) >>a表示将数据放入a对象中。
2) <<a表示将a对象中存储的数据拿出。
标准输入流
标准输入流对象cin,重点掌握的函数
cin.get() //一次只能读取一个字符
cin.get(一个参数) //读一个字符
cin.get(两个参数) //可以读字符串
cin.getline()
cin.ignore()
cin.peek()
cin.putback()
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#if 0
标准输入流对象cin,重点掌握的函数
cin.get() //一次只能读取一个字符
cin.get(一个参数) //读一个字符
cin.get(两个参数) //可以读字符串
cin.getline()
cin.ignore()
cin.peek()
cin.putback()
#endif
void test01(){
//1. cin.get cin.get(c).get(d);
char c = cin.get();
cout << "c:" << c << endl;
c = cin.get();
cout << "c:" << c << endl;
c = cin.get();
cout << "c:" << c << endl;
c = cin.get();
cout << "c:" << c << endl;
}
//按行读取
void test02(){
char buf[1024] = { 0 };
#if 0
cin.get(buf, 1024); //读到换行结束,换行不读取,留在缓冲区
char c = cin.get();
if (c == '\n'){
cout << "换行符还在缓冲区!" << endl;
}
#else
cin.getline(buf,1024); //读取换行,并且把换行扔掉了
char c = cin.get();
if (c == '\n'){
cout << "换行符还在缓冲区!" << endl;
}
#endif
cout << buf;
}
void test03(){
//忽略当前指定个数的字符,没有参数,默认是当前一个字符
cin.ignore(2);
char c = cin.get();
cout << "c:" << c << endl;
}
void test04(){
//偷窥下缓冲区当前字符,但是不拿走,和get相反,get看了并且要拿走
//比如输入: as
char c = cin.peek();
cout << "c:" << c << endl;
char d = cin.get();
cout << "d:" << d << endl;
c = cin.peek();
cout << "c:" << c << endl;
}
void test05(){
//比如输入: as
char c = cin.get();
cin.putback(c);
char buf[1024] = { 0 };
cin.getline(buf,1024);
cout << buf << endl;
}
void test06(){
cout << "请输入一个数字或者一个字符串:" << endl;
char c = cin.get();
if (c >= '0' && c <= '9'){
//把字符放回去
cin.putback(c);
int number;
cin >> number;
cout << "您输入的是数字:" << number << endl;
}
else{
//把字符放回去
cin.putback(c);
char buf[1024] = { 0 };
cin >> buf;
cout << "您输入的是字符串:" << buf << endl;
}
}
int main(){
//test01();
//test02();
//test03();
//test04();
//test05();
test06();
system("pause");
return EXIT_SUCCESS;
}
标准输出流
字符输出
cout.flush() //刷新缓冲区
cout.put() //向缓冲区写字符
cout.write() //从buffe中写num个字节到当前输出流中。
//cout.flush 刷新缓冲区,linux下有效
void test01(){
cout << "hello world";
//刷新缓冲区
cout.flush();
}
//cout.put 输出一个字符
void test02(){
cout.put('a');
//链式编程
cout.put('h').put('e').put('l');
}
//cout.write 输出字符串 buf,输出多少个
void test03(){
//char* str = "hello world!";
//cout.write(str, strlen(str));
char* str = "*************";
for (int i = 1; i <= strlen(str); i ++){
cout.write(str, i);
cout << endl;
}
for (int i = strlen(str); i > 0; i --){
cout.write(str, i);
cout << endl;
}
}
使用流对象的有关成员函数
通过调用流对象cout中用于控制输出格式的成员函数来控制输出格式。用于控制输出格式的常用的成员函数如下:
流成员函数setf和控制符setiosflags括号中的参数表示格式状态,它是通过格式标志来指定的。格式标志在类ios中被定义为枚举值。因此在引用这些格式标志时要在前面加上类名ios和域运算符“::”。格式标志见表13.5。
控制符格式化输出
//通过流成员函数
void test01(){
int number = 99;
cout.width(20);
cout.fill('*');
cout.setf(ios::left);
cout.unsetf(ios::dec); //卸载十进制
cout.setf(ios::hex);
cout.setf(ios::showbase);
cout.unsetf(ios::hex);
cout.setf(ios::oct);
cout << number << endl;
}
//使用控制符
void test02(){
int number = 99;
cout << setw(20)
<< setfill('~')
<< setiosflags(ios::showbase)
<< setiosflags(ios::left)
<< hex
<< number
<< endl;
}
文件流类和文件流对象
和文件有关系的输入输出类主要在fstream.h这个头文件中被定义,在这个头文件中主要被定义了三个类,由这三个类控制对文件的各种输入输出操作,他们分别是ifstream、ofstream、fstream,其中fstream类是由iostream类派生而来,他们之间的继承关系见下图所示:
在定义文件流对象时指定参数
在声明文件流类时定义了带参数的构造函数,其中包含了打开磁盘文件的功能。因此, 可以在定义文件流对象时指定参数,调用文件流类的构造函数来实现打开文件的功能。
文本文件的读写
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
using namespace std;
class MyClass{
public:
bool operator!(){
return flag == 0 ? false : true;
}
public:
int flag;
};
void test01(){
//写文件
//ofstream os("./test.txt",ios::out | ios::trunc);
ofstream os; //文件输出流对象
os.open("./test.txt", ios::out | ios::trunc);
//if (!os.is_open()){
// cout << "文件打开失败!" << endl;
//}
if (!os){
cout << "文件打开失败!" << endl;
}
os << "姓名:Obama" << endl;
os << "年龄:20" << endl;
os << "性别:男" << endl;
os.close();
}
void test02(){
ifstream is("./test.txt",ios::in);
if (!is){
cout << "文件打开失败!" << endl;
}
char buf[1024] = { 0 };
//每次读取一行数据
while (is >> buf){
cout << buf << endl;
}
//关闭文件
is.close();
}
int main(){
test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
二进制文件的读写
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
using namespace std;
class Person{
public:
Person(){}
Person(char* name,int age){
strcpy(this->name, name);
this->age = age;
}
public:
char name[64];
int age;
};
void test(){
//创建两个对象
Person p1("Obama", 10);
Person p2("John", 20);
//写文件
ofstream os("./persons.txt",ios::out | ios::binary | ios::trunc);
if (!os){
cout << "打开文件失败!" << endl;
return;
}
os.write((const char*)&p1,sizeof(Person));
os.write((const char*)&p2, sizeof(Person));
os.close();
//从文件中读取person对象
ifstream is("./persons.txt",ios::in | ios::binary);
if (!is.is_open()){
cout << "文件打开失败!" << endl;
return;
}
//从文件中读取数据
//开辟两个对象的空间
Person p3;
Person p4;
is.read((char*)&p3, sizeof(Person));
is.read((char*)&p4, sizeof(Person));
cout << "Name:" << p3.name << " Age:" << p3.age << endl;
cout << "Name:" << p4.name << " Age:" << p4.age << endl;
is.close();
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}