1 输入流类
![在这里插入图片描述](https://img-blog.csdnimg.cn/a16adabeb53347eca16debc65c5c2469.png)
cin是istream事先预定义好的实例
![在这里插入图片描述](https://img-blog.csdnimg.cn/51951537a64f45558222cfdf7c4d17f7.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ3ODY1OQ==,size_16,color_FFFFFF,t_70)
打开文件时与输出流类相同,用按位或增加条件“|”
![在这里插入图片描述](https://img-blog.csdnimg.cn/4e69921642e74c8590e39fc770bb8312.png)
一般来讲,输入尽量少用各种格式控制
①<<:插入运算符,相当于把内存中数据插入到输出流中,进而让其输出到标准输出、文件、字符串
②>>:提取运算符,输入流中有标准输入、文件、字符串中输入的数据,在计算机内存中设置一个变量a来提取输入流中的数据,来接应这个数据(cin >> a,is >> v,read函数)
![在这里插入图片描述](https://img-blog.csdnimg.cn/30c63d81dd9e491eaa2acb226be10940.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ3ODY1OQ==,size_16,color_FFFFFF,t_70)
2 get函数与cin的区别、put函数
get函数可以读取空格,cin不能读取空格
put函数会向输出对象写入一个字符:void put(char ch)
#include <iostream>
using namespace std;
int main()
{
char ch;
while ((ch = cin.get()) != EOF)//EOF表示crtl+z取消输入
cout.put(ch); //
return 0;
}
输入:h a p p y
输出:h a p p y
int main()
{
char ch;
while (cin >> ch)
cout.put(ch); //与cout << ch相同
return 0;
}
输入:h a p p y
输出:happy
cin << 不能读入含有空格的字符串
int main()
{
string ch;
cin >> ch;
cout << ch;
return 0;
}
输入:fdssd dfsf
输出:fdssd
3 getline函数
详细见此,两种getline函数
①包含在< string >中,读取的istream是作为参数is传进函数的。读取的字符串保存在string类型的str中
getline (istream& is, string& str, char delim);
② 包含在< istream>中。从istream中读取至多n个字符(包含结束标记符)保存在s对应的数组中。即使还没读够n个字符,如果遇到delim或字数达到限制,则读取终止,delim都不会被保存进s对应的数组中。
getline (char* s, streamsize n, char delim )
实例:
int main()
{
string line;
cout << "终止字符为t!" << endl;
getline(cin, line, 't'); //从标准输入设备输入,存到line中,遇到t终止
cout << line << endl;
return 0;
}
终止字符为t!
输入:
abcde
fg hijkt
输出:
abcde
fg hijk
3 文件输入流类
①从文件中读取二进制,记录到一个结构中
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct SalaryInfo {
unsigned id;
double salary;
};
int main() {
SalaryInfo employee1 = { 600001, 8000 };//顺序初始化结构体
ofstream os("payroll", ios_base::out | ios_base::binary); //二进制输出到"payroll"文件中
os.write(reinterpret_cast<char*>(&employee1), sizeof(employee1));//第一个参数是转换为char*的employee的地址
//第二个参数是要写入的字节数,此处为全部字节
os.close(); //切记关闭文件
ifstream is ("payroll", ios_base::in | ios_base::binary); //输入流is从文件"payroll"至内存中,形式为二进制
if (is) { //输入流中有数据
SalaryInfo employee2;
is.read(reinterpret_cast<char*>(&employee2), sizeof(employee2));
cout << employee2.id << " " << employee2.salary << endl;
}
else {
cout << "error:不能打开文件payroll" << endl;
}
is.close(); //切记关闭文件
return 0;
}
②用 seekg 函数设置位置指针,找到文件中0元素的位置
interger:整数
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
int a[] = { 3, 7, 2, 0 ,5, 1, 0 };
ofstream os("integers", ios_base::out | ios_base::binary); //写入到文件中
os.write(reinterpret_cast<char*>(&a), sizeof(a)); //sizeof(数组名)表示整个数组所占空间
os.close();
ifstream is("integers", ios_base::in | ios_base::binary); //在构造的时候声明文件,或是用open来关联
if (is) {
is.seekg(3 * sizeof(int)); //将读取数据位置的指针向右移动三个int所占字节的长度
int v;
is.read(reinterpret_cast<char*>(&v), sizeof(int)); //读取一个int数据到v中
cout << "第4个数为:" << v << endl;
}
else {
cout << "error" << endl;
}
ifstream file("integers", ios_base::in | ios_base::binary);
if (file) { //方便打印错误信息
while (file) { //读到文件尾file为0
streampos here = file.tellg();
int v;
file.read(reinterpret_cast<char*>(&v), sizeof(int)); //每次用v提取输入流中的一个int类型数据,所以每次循环tellg()返回的指针右移
if (file && v == 0) //file没读到尾,且v==0
cout << "Position " << here << " is 0" << endl;
}
}
else {
cout << "error" << endl;
}
file.close();
return 0;
}
输出:
第4个数为:0
Position 12 is 0 //从0开始计数
Position 24 is 0
4 streampos类型
streampos定义为long型,是文件指针的值,用于随机存储。
streampos是在stream中的绝对位置,非负。
streamoff是与stream中指定点的相对位置,可以是负数。
tellg/tellp的返回值是streampos,返回的是与stream起点的距离。
seekg/seekp如果只有一个输入参数,那么这个参数类型为streampos;
seekg/seekp如果有两个输入参数,那么第一个参数类型为streamoff。
例如,seekg(streamoff, ios_base::end),这里是将读入点的位置放到与stream结尾相对位置为streamoff的地方,肯定非正。
5 字符串输入流
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
template <class T>
inline T fromString(const string& str) {
istringstream is(str); //构造时设置字符串
T v;
is >> v; //用T类型的v提取字符串输入流is中的数据
return v;
}
int main()
{
cout << fromString<int>("5") << endl;
cout << fromString<double>("6.2342") << endl;
return 0;
}
读取的来源不是程序空间外的某个文件,而是程序空间内的字符串;通过字符串输入流实现了字符串转换为其他类型数据。
6 输入/输出流
fstream对象支持文件的既读又写
stringstream对象支持字符串的输入和输出