一、标准输入输出流
C++ 的输入输出是程序与用户或外部设备(如文件、网络等)之间交换信息的过程。
C++ 提供了丰富的标准库来支持这种交互,主要通过流的概念来实现。
流:抽象概念,表示一连串的数据(字节或字符),数据按先进先出的顺序传输。
输入流是从外部源到程序的数据传输,而输出流则是从程序到外部目标的数据传输。
C++输入/输出类的层次结构
解释:
ios_base:这是IO流的基本信息类,它定义了所有IO流共有的属性和行为。
ios:这是IO流的基类,它继承自ios_base。ios类提供了通用的输入和输出功能。
istream:这是一个通用的输入类,它继承自ios。
cin对象是istream的一个实例,用于从标准输入(通常是键盘)读取数据。
ostream:这是一个通用的输出类,它继承自ios。
cout和cerr对象都是ostream的实例,分别用于向标准输出(通常是屏幕)和错误 输出写入数据。
iostream:这是一个通用的输入/输出类,它同时继承自istream和ostream。
iostream类可以进行双向的数据传输。
ifstream:这是一个文件输入类,它继承自istream。ifstream类用于从文件中读取数据。
ofstream:这是一个文件输出类,它继承自ostream。ofstream类用于向文件中写入数据。
fstream:这是一个文件输入/输出类,它同时继承自ifstream和ofstream。
fstream类可以对文件进行双向的数据传输。
输入输出cin/cout和提取符和操作符:
在C++中,cin 和 cout 是两个常用的I/O流对象,它们分别代表标准输入流和标准输出流。
在C++中,>> 和 << 是两个常用的流操作符,它们分别用于从输入流中读取数据和向输出流写入数据。
通常两者结合
#include<iostream>
int main()
{
int a;
std::cin >> a;
std::cout << a;
return 0;
}
//输入:1
//输出结果是:1
get与getline函数:
get和getline函数都有两个用法 :
std::cin.get和std::get,std::cin.getline和std::getline
std::cin.get和std::cin.getline是在std::istream 类的成员函数
std::get和std::getline是标准库里的函数
两者的区别:
处理换行符:getline函数在读取完一行后会自动丢弃换行符,而get函数(特别是带有分隔符的版本)会保留分隔符(通常是换行符)在输入队列中。
目标容器:get通常用于填充字符数组,而std::getline的全局版本可以直接读入std::string。
自动终止:getline在达到指定长度或遇到分隔符时会自动停止并处理字符串结束标志,而使用get时可能需要手动处理字符串的结束。
get函数的使用:
std::get
std::get一般为访问一些容器中的元素:
举例子:
访问元组里的元素
std::tuple<int, std::string> my(10, "Test");
int i = std::get<0>(my);
// 访问第一个元素,类型为 int
std::string s = std::get<1>(my);
// 访问第二个元素,类型为 std::string
// 这里,get 是模板函数,它的模板参数是元素的位置(从0开始),返回对应类型引用。
std::cin.get
1.std::cin.gin()
这个版本没有参数,它从输入流中读取下一个字符,包括空格和换行符。
如果到达文件尾或者遇到错误,它会返回 EOF(通常定义为 -1),否则返回读取字符的 ASCII 值。
功能:主要是读入缓存区里的换行符
2.std::cin.get(a)
a是要输入数据的变量名
3.std::cin.get(a,b)
a是要输入数据的变量名,b是要读入的字符数会读入n-1个字符,最后一个是'/0'
4.std::cin.get(a,b,c)
a是要输入数据的变量名,b是要读入的字符数会读入n-1个字符,最后一个是'/0',c是要遇到哪个字符就提前结束输入
getline函数的使用:
std::getline
针对于string容器、
有两种常用的用法:
istream& getline(istream& is, string& str);
从输入流is读取字符直到遇到换行符(\n),并将读取的内容(不包括换行符)存入str中。
#include<iostream>
#include<string>
int main()
{
std::string a;
std::getline(std::cin, a);
std::cout << a;
return 0;
}
如果之前str已有内容,这些内容会被新读取的字符串覆盖。
istream& getline(istream& is, string& str, char delim);
同上,但允许用户指定分隔符delim。
当遇到此分隔符时停止读取,并将读取的内容(不包括分隔符)存入str。
#include<iostream>
#include<string>
int main()
{
std::string a;
std::getline(std::cin, a,'a');
std::cout << a;
return 0;
}
std::cin.getline
istream& getline(char* s, streamsize n);
从输入流读取最多n个字符(不包括终止的空字符'\0')到字符数组s中。
如果在读取n-1个字符之前遇到文件结束或换行符,则停止读取,并在s末尾添加'\0'。
istream& getline(char* s, streamsize n, char delim);
类似于上一个版本,但读取会在遇到delim字符或读取n-1个字符后停止,并在s末尾添加'\0'。
二、文件输入输出流:
程序运行时,产生的数据都属于临时数据,程序一旦运行结束就会被释放,通过文件可以将数据持久化。
C++中对文件进行操作需要包含头文件<fstream>
文件类型:
文本文件-文件以文本的ASCII码形式存储在计算机中
二进制文件-文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂他们
操作文件的三大类:
ofstream:写操作 ifstream:读操作 fstream:读写操作
ios::in | 为输入(读)而打开文件 |
ios::out | 为输出(写)而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 所有输出附加在文件末尾 |
ios::trunc | 如果文件已存在则先清空该文件,若文件不存在则创建文件 |
ios::binary | 二进制方式打开,不做字符转换(别用string 有大bug) |
这些表示符可以 用 | 进行组合
写文件:
简单的写一个文件:
#include<iostream>
#include<fstream>
int main()
{
std::ofstream is;
is.open("test.txt",std::ios::out);
is << "aaaa";
is.close();
return 0;
}
如果不指定文件路径,默认和你项目的文件路径一样
运行结果:
实际产生的文件:
也可以使用write进行写文件
流对象.write(指向要写入数据的缓冲区的指针,字节数)
读文件:
#include<iostream>
#include<fstream>
int main()
{
std::ifstream os;
os.open("test.txt",std::ios::in);
//第一种
/*char put[10] = { 0 };
while (os>>buf)
{
std::cout << put << endl;
}*/
//第二种
/*char buf[10] = { 0 };
while (ifs.getline(put,sizeof(put)))
{
std::cout << put << endl;
}*/
//第三种
/*#include<string>
string put;
while (getline(os,buf))
{
std::cout << put << endl;
}*/
//第四种-不推荐
char c;
while ((c = os.get()) != EOF)
{
std::cout << c;
}
os.close();
return 0;
}
结果是: