编译器:

gcc / g++

C++IO流

流的概念

流就是若干字节组成字节序列,流操作从一个到另一个移动的过程

流中的内容:二进制数据 ASCII码

流类体系

C++中用类实现所有流类操作

  • 标准的输入输出流
  • C++格式控制
  • 字符流
  • 文件流
#include <iostream>  //istream ostream
#include <fstream> //ifstream ofstream
#include <strstream> //istringstream
using namespace std;
int main(int argc, char** argv) {
fstream out;
ifstream iin;
return 0;
}

标准输入输出流

对象

类型

作用

cin

标准输入

从键盘读取,可以重定向

cout

标准输出

输出到控制台,可以重定向

cerr

标准错误输出

输出到控制台,不可以重定向

clog

标准错误输出

输出到控制台,可重定向

#include <iostream>
using namespace std;
int main(int argc, char** argv) {
cout << "标准输出" << endl;
cerr << "标准错误" << endl;
clog << "标准错误" << endl;
return 0;
}

字符和字符串输入

  • cout成员函数
  • put() : 输出一个字符
  • write(): 输出字符串
  • cin成员函数
  • get():输入一个字符
  • getline: 输入一个字符串
#include <iostream>
using namespace std;
int main(int argc, char** argv) {

cout << "标准输出" << endl;
cerr << "标准错误" << endl;
clog << "标准错误" << endl;
//字符输入
cout << "字符输入:" << endl;
int userKey = cin.get();
cout.put(userKey);
char str[10] = { "" };
cout << "字符串输入:" << endl;
while (getchar() != '\n');
cin.getline(str, 10); //10个长度包含\0
cout << str << endl;
cout.write(str, 10);
return 0;
}

C++格式控制

  • 包含头文件: iomanip
  • 通过对象的形式,一种通过成员的函数形式

对象形式

实际含义

setbase(n)

设置多少进制输出整数(参数是8和16)

setw(n)

设置输出数据宽度(默认对齐是右对齐,不足补空格)

setiosflags(ios::left)

设置对齐方式: ios::left ,ios::right

setprecition(n)

单纯使用是控制有效位数,如果控制小数位数结合fixed

setfill(n)

填充字符

#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, char** argv) {
//进制输出
cout << setbase(16) << 32 << endl;
cout << setbase(8) << 32 << endl;
cout <<showbase<< hex << 32 << endl;
cout << dec << 32 << endl;
cout << noshowbase<<oct << 32 << endl;

//cout << setbase(2) << 32 << endl; //无效
//默认右对齐
cout << setw(10) << "姓名" << setw(10) << "年龄" << setw(10) << "编号" << endl;
cout << setw(10) << "小芳" << setw(10) << 17 << setw(10) << 119911 << endl;
cout << setiosflags(ios::left);
cout << setw(10) << "姓名" << setw(10) << "年龄" << setw(10) << "编号" << endl;
cout << setw(10) << "小芳" << setw(10) << 17 << setw(10) << 119911 << endl;
cout << setprecision(4) << 300.12345 << endl; //直接用控制的是有效位数
cout << fixed<<setprecision(4) << 300.12349 << endl; //小数位数
cout << setiosflags(ios::scientific) << 300.12345 << endl;

//所有的格式控制存在成员函数的调用形式
cout.width(8);
cout << "姓名";
cout.width(8);
cout << 1 << endl;
cout.precision(4);
//取消上述格式
cout <<resetiosflags <<300.333 << endl;
bool num = 1;
cout << boolalpha << num << endl; //true和false形式输出bool类型
return 0;
}

字符流

  • 包含头文件: sstream
  • istringstream
  • ostringstream
  • stringstream
  • 一般处理字符流的时候用的是stringstream类型的对象
  • 获取字符流中的stirng
  • string str(); //获取string
  • void str(const string& str) //重置流对象中字符串
  • 字符流做什么
  • 数据类型的转换
  • 数据的分割
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
stringstream stream("ILoveyou");
cout << stream.str() << endl;
char str[20] = "";
stream >> str;
cout << str << endl;
stream.str(""); //清除

//数据类型转换
//整数转字符串,字符串转数字
string num = to_string(123);
cout << num << endl;
int inumber = 12123;
char result[20] = { "" };
stringstream buf(result);
buf << inumber;
buf >> result;
cout << result << endl;

stringstream strNum("12345435");
int dataNum = 0;
strNum >> dataNum;
cout << dataNum << endl;
//数据切割(流中默认空格作为单一数据的间隔)
stringstream ip("ip: 192.168.1.1");
char strip[20] = { "" };
ip >> strip; //ip: 拿出来
int ipNum[4];
char userKey;
ip >> ipNum[0];
ip >> userKey;

ip >> ipNum[1];
ip >> userKey;

ip >> ipNum[2];
ip >> userKey;

ip >> ipNum[3];
for (int i = 0; i < 4; i++) {
cout << ipNum[i] << "\t";
}
cout << endl;
//注意点: 流在做转换的,必须调用clear清除处理
buf.clear();
buf << inumber;
buf >> result;
cout << result << endl;

return 0;
}

文件操作流

  • 包含头文件: fstream
  • ofstream: 打开文件只能写操作
  • ifstream: 打开文件只读操作
  • 一般大家创建一个fstream对象,可读可写
  • 打开文件
  • 构造的方式,带参数构造函数:const char* URL,ios::openmode mode
  • 成员函数方式: void open(const char* URL,ios::openmode mode)
  • 判断文件打开是否成功
  • !is_open()函数判断是否打开成功 ,!is_open()是1的打开失败
  • !文件对象 .!对象是1打开失败

读写方式

作用

ios::in

读的方式打开文件

ios::out

写的方式打开文件

ios::app

追加写文件

ios::ate

打开已有文件,指针在文件末位

ios::trunc

文件不存在具有创建方式

ios::binary

二进制打开,默认打开方式ASCII码

ios::nocreate

不创建

ios::noreplace

不替换

组合方式: 用位或, 可读可写: ios::in|ios::out

  • 关闭文件
  • close关闭文件
  • 文件读写
  • 直接采用>> <<符号进行读写
  • 采用成员函数读写:read函数和write成员函数
  • 文件指针移动
  • ifstream文件指针
  • ifstream& seekg(long int pos);
  • ifstream& seekg(long int pos,ios_base::seekdir begin);
  • ofstream文件指针
  • ofstream& seekp(long int pos);
  • ofstream& seekp(long int pos,ios_base::seekdir begin);
  • begin:
  • ios::beg 开始位置
  • ios::cur 当前位置
  • ios::end 结束位置
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
class MM {
public:
MM() {}
MM(string name, int age, int num) : name(name), age(age), num(num) {}
void print() { cout << name << "\t" << age << "\t" << num << endl; }
//采用>> <<
void saveFile(string fileName) {
fstream file(fileName, ios::in | ios::out | ios::app);
if (!file) {
cout << "打开文件失败!" << endl;
return;
}
file << name << " " << age << " " << num << endl;
file.close();
}
void readFile(string fileName) {
fstream file(fileName, ios::in);
if (!file) {
cout << "打开文件失败!" << endl;
return;
}
while (true) {
MM temp;
file >> temp.name >> temp.age >> temp.num;
if (file.eof()) {
break;
}
temp.print();
}
file.close();
}

protected:
string name;
int age;
int num;
};

void asciiRWFile(string readFile, string writeFile) {
//流的方式
//字符或者字符串的
fstream read(readFile, ios::in);
fstream write(writeFile, ios::out);
while (!read.eof()) {
char userkey = read.get(); // getline()
write.put(userkey); // write()函数
}
read.close();
write.close();
}
//二进制读写
void binaryRWFile(string readFile, string writeFile) {
fstream r(readFile, ios::in | ios::binary);
fstream w(writeFile, ios::out | ios::binary);
while (!r.eof()) {
char str[1024] = {""}; //缓冲区
r.read(str, 1024);
w.write(str, strlen(str)); //长度写多少就写入文件多少
}
r.close();
w.close();
}
//文件指针移动
int getSize(string fileName) {
fstream read(fileName, ios::in | ios::binary);
read.seekg(0, ios::end);
int size = read.tellg();
read.close();
return size;
}

int main(int argc, char** argv) {
//打开文件测试
// fstream file("xxoo.txt",ios::in|ios::out|ios::trunc);
//等效下面两行
fstream file;
file.open("xxoo.txt", ios::in | ios::out | ios::trunc);
if (!file || !file.is_open()) {
cerr << "文件打开失败" << endl;
}
file.close();
MM mm("xxx", 18, 1001);
mm.saveFile("mm.txt");
mm.readFile("mm.txt");

asciiRWFile("mm.txt", "xxoo.txt");
binaryRWFile("xxoo.txt", "rw.txt");
cout << "size:" << getSize("size.txt") << endl;
return 0;
}
//用write写入对象数组数据放到文件
//用read把数据读取出来,可以存储到对象数组中,打印出来
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
class MM {
public:
MM() {}
MM(const char* name, int age, int num) : age(age), num(num) {
strcpy(this->name, name);
}
void writeFile(const char* fileName) {
fstream fread(fileName, ios::out | ios::app | ios::binary);
fread.write((char*)this, sizeof(MM));
fread.close();
}
friend ostream& operator<<(ostream& out, const MM& object);

protected:
char name[20];
int age;
int num;
};
ostream& operator<<(ostream& out, const MM& object) {
out << object.name << "\t" << object.age << "\t" << object.num << endl;
return out;
}
void readFile(const char* fileName, MM* temp, int size) {
fstream fread(fileName, ios::in | ios::binary);
// char str[1024] = { "" };
while (1) {
if (fread.eof())
break;
fread.read((char*)temp, size);
}
fread.close();
}

int main(int argc, char** argv) {
{
// MM array[3] = { {"张三",18,1001},{"小美",28,1002},{"小丽",38,1003} };
// MM temp[3];
// readFile("mm.txt", temp, 3 * sizeof(MM));
// for (int i = 0; i < 3; i++)
//{
// cout << temp[i];
//}
}
cout << "dsafdsfasda" << endl;
fstream read("xx.txt", ios::in | ios::trunc | ios::_Nocreate);
// ios::app: 追加方式,不能替换原文件
if (!read) {
cout << "文件打开失败!" << endl;
return 0;
}
read.close();
return 0;
}