1 流的概述
C++流是读写(输入与输出)逻辑的通用实现,让用户能够用统一的模式读写数据。不管是磁盘或键盘读取数据,还是将输入写入显示器或磁盘,模式都一样
用于写入流时,运算符<<被称为流插入运算符,可将其用于写入屏幕、文件等;从流中读取数据时,运算符>>被称为流提取运算符,可将其用于从键盘、文件等读取输入
2 流类和流对象
类/对象 | 用途 |
---|---|
cout | |
cin | |
cerr | |
fstream | |
ofstream | |
ifstream | |
stringstream |
cout、cin、cerr分别是流类ostream、istream、ostream的全局对象,其在main()开始前就已初始化
使用流类时,可指定控制符
类/对象 | 用途 |
---|---|
输出控制符 | |
endl | |
ends | |
基数控制符 | |
dec | |
hex | |
oct | |
浮点数表示控制符 | |
fixed | |
scientific | |
< iomanip > 控制符 | |
setprecision | |
setw | |
setfill | |
setbase | |
setiosflag | |
resetiosflag |
3 std::cout:将指定格式的数据写入控制台
3.1 修改数字显示格式
3.2 对齐文本和设置字段宽度
4 std::in进行输入
4.1 将输入读取到基本类型变量
4.2 使用std::cin:get将输入读取到cha* 缓冲区
在读取c风格字符串时,可以将输入直接写入char数组:
char charBuf[10]={0};
cin>>charBuf;
当用户输入超过10个字符时比较危险,数组缓冲区越界导致程序崩溃。更好的方法是:
char charBuf[10]={0};
cin.get(charBuf,9);
尽量不使用char数组,只要允许应该使用std::string
4.3 将输入读取到std::string中
示例:
int main(){
cout<<"Enter your name: ";
string name;
cin>>name;
cout<<"Hi "<<name<<endl;
}
输出:
Enter your name: Siddhartha Rao
Hi Siddhartha
由于cin遇到空白后就停止插入,所以只显示了名字
要读取整行输入(包括空白),需使用getline(),修改如下:
int main(){
cout<<"Enter your name: ";
string name;
getline(cin,name);
cout<<"Hi "<<name<<endl;
}
输出:
Enter your name: Siddhartha Rao
Hi Siddhartha Rao
5 使用std::fstream处理文件
std::fstream旨在以独立于平台的方式访问文件。其从std::ofstream继承了写入文件的功能,从std::ifstream继承了读取文件的功能。要使用std::fstream类或其基类,需包含头文件
5.1 使用open()和close()打开和关闭文件
要写入数据到文件或者从文件读取数据,首先使用方法open()打开文件:
fstream myFile;
myFile.open("HelloFile.txt",ios_base::in|ios_base::out|ios_base::trunc);
if(myFile.isopen()){ //检查文件是否打开
//读或写操作
myFile.close();
}
open()接受两个参数:
-
第一个是要打开的文件路径和名称(若没有提供路径,将假定为应用程序的当前目录)
-
第二个是文件的打开模式,有以下几种
- ios_base::app:附加到现有文件末尾,而不是覆盖
- ios_base::ate:切换到文件末尾,但可在文件任何位置写入数据
- ios_base::trunc:覆盖现有文件,这是默认设置
- ios_base::binary:创建二进制文件
- ios_base::in:以只读方式打开文件
- ios_base::out:以只写方式打开文件
关于是用ios::还是用ios_base::,目前有点疑惑???TODO...
建议在使用文件流对象前,使用is_open()检查文件打开操作是否成功
保存到文件时,必须使用close()关闭文件流
也可使用构造函数打开文件流:
fstream myFile("HelloFile.txt",ios_base::in|ios_base::out|ios_base::trunc);
如果只想打开文件进行写入,可使用如下代码:
ofstream myFile("HelloFile.txt",ios_base::out);
如果只想打开文件进行读取,可使用如下代码:
ifstream myFile("HelloFile.txt",ios_base::in);
5.2 使用open()创建文本文件和运算符<<写入文本
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
ofstream myFile;
myFile.open("HelloFile.txt", ios_base::out);
if (myFile.is_open())
{
cout << "File open successful" << endl;
myFile << "My first text file!" << endl;
myFile << "Hello file!";
cout << "Finished writing to file, will close now" << endl;
myFile.close();
}
return 0;
}
5.3 使用open()和运算符>>读取文本
#include<fstream>
#include<iostream>
#include<string>
using namespace std;
int main()
{
ifstream myFile;
myFile.open("HelloFile.txt", ios_base::in);
if (myFile.is_open())
{
cout << "File open successful. It contains: " << endl;
string fileContents;
while (myFile.good())
{
getline (myFile, fileContents);
cout << fileContents << endl;
}
cout << "Finished reading file, will close now" << endl;
myFile.close();
}
else
cout << "open() failed: check if file is in right folder" << endl;
return 0;
}
5.4 读写二进制文件
#include<fstream>
#include<iomanip>
#include<string>
#include<iostream>
using namespace std;
struct Human
{
Human() {};
Human(const char* inName, int inAge, const char* inDOB) : age(inAge)
{
strcpy(name, inName);
strcpy(DOB, inDOB);
}
char name[30];
int age;
char DOB[20];
};
int main()
{
Human Input("Siddhartha Rao", 101, "May 1916");
ofstream fsOut ("MyBinary.bin", ios_base::out | ios_base::binary);
if (fsOut.is_open())
{
cout << "Writing one object of Human to a binary file" << endl;
fsOut.write(reinterpret_cast<const char*>(&Input), sizeof(Input));
fsOut.close();
}
ifstream fsIn ("MyBinary.bin", ios_base::in | ios_base::binary);
if(fsIn.is_open())
{
Human somePerson;
fsIn.read((char*)&somePerson, sizeof(somePerson));
cout << "Reading information from binary file: " << endl;
cout << "Name = " << somePerson.name << endl;
cout << "Age = " << somePerson.age << endl;
cout << "Date of Birth = " << somePerson.DOB << endl;
}
return 0;
}
6 使用std::stringstream对字符串进行转换
要使用std::stringstream类,需要包含头文件