1. C语言的输入与输出
int main()
{
int i = 1;
double d = 2.222;
//下面的cout是调用了两个不同的函数
cout << i;// ->cout.operator<<(i);
cout << d;// ->cout.operator<<(d);
//可以理解为 内存里的i流向了cout控制台
//内置类型我们可以直接用cout<< cin>>
//库里面实现了
//自定义类型就需要我们自己重载,才可以用 (这样更方便)
cin >> i;
cin >> d;
//从控制台提取内容到内存里去了
//两者皆可以支持连续的输入和输出
cout << i << d;//两个operator<<函数调用
//怎么做到的(回忆)?
//返回cout和cin的引用
//输入可以用空格和换行当作 默认换行和间隔
// scanf/printf的缺点是只能支持内置类型
// cout<< / cin>> 的优势:自己重载以后,自定义类型对象可以简单实用
return 0;
}
int main()
{
string str;
while (cin >> str)//此处返回的是istream类型的对象is
{
cout << str << endl;
}
//问题:istream类型的对象is为什么可以做逻辑判断
// 整形,指针可以做判断
//有一个叫做类型运算符重载,当你用istream时,可以将其转换为一个bool值
char* a;
while (scanf("%s", a) != EOF)
{
cout << a << endl;
}
//二者效果一样
//scanf如果成功,会返回一个整数。失败会返回EOF
//结束:ctrl+z/c
//本质都是发一个信号
return 0;
}
2. 流是什么
“流”即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且具有方向性的数据( 其单位可以是bit,byte,packet )的抽象描述。 C++流是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。
它的特性是:有序连续、具有方向性
为了实现这种流动,C++定义了I/O标准类库,这些每个类都称为流/流类,用以完成某方面的功能
3. C++IO流
// c语言的方式进行读写
// 使用文件IO流用文本及二进制方式演示读写配置文件
struct ServerInfo
{
char _ip[32]; // ip
int _port; // 端口
};
void TestC_W_Bin()//二进制写
{
ServerInfo info = { "127.0.0.1", 80 };
// fopen/fclose
// 二进制读写 fwrite/fread 写出去的东西,文件中看不见
// 文本读写 fprintf/fscanf
FILE* fout = fopen("test.bin", "wb");
assert(fout);
fwrite(&info, sizeof(info), 1, fout);
fclose(fout);
}
void TestC_R_Bin()//二进制读
{
FILE* fin = fopen("test.bin", "rb");
assert(fin);
ServerInfo info;
fread(&info, sizeof(info), 1, fin);
fclose(fin);
printf("%s:%d\n", info._ip, info._port);
}
void TestC_W_Text()//文本写
{
FILE* fout = fopen("test.txt", "w");
assert(fout);
ServerInfo info = { "127.0.0.1", 80 };
fprintf(fout, "%s\n%d", info._ip, info._port);
//此处中间要加分割符(任意即可)(空格或者换行),否则输出会出现乱码
fclose(fout);
}
void TestC_R_Text()//文本读
{
FILE* fin = fopen("test.txt", "r");
assert(fin);
ServerInfo info;
fscanf(fin, "%s%d", info._ip, &info._port);
fclose(fin);
printf("%s:%d\n", info._ip, info._port);
}
int main()
{
TestC_W_Bin();
TestC_R_Bin();
TestC_W_Text();
TestC_R_Text();
return 0;
}
c++的IO操作
class Date
{
friend ofstream& operator<<(ofstream& ofs, Date& d);
public:
Date(int year = 2022, int month = 1, int day = 1)
:_year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
//ostream& operator<<(ostream& os, const Date& d)
ofstream& operator<<(ofstream& ofs, Date& d)
{
ofs << d._year << " " << d._month << " " << d._day << endl;
return ofs;
}
struct ServerInfo
{
char _ip[32]; // ip
int _port; // 端口
Date _d;
};
//使用C++等方式进行IO
class ConfigManager
{
public:
ConfigManager(const char* filename)
:_filename(filename)
{}
void WriteBin(const ServerInfo& info)//以二进制的方式写
{
// 下面的 “|” 相当于Linux中的管道
ofstream ofs(_filename.c_str(), ios_base::out | ios_base::binary);
//不需要手动的close,他有析构函数,会自动close
ofs.write((const char*)&info, sizeof(ServerInfo));
//字节流和二进制流都可以写入
}
void ReadBin(ServerInfo& info)//以二进制的方式读
{
ifstream ifs(_filename.c_str(), ios_base::in | ios_base::binary);
ifs.read((char*)&info, sizeof(ServerInfo));
}
void WriteText(ServerInfo& info)//文本写
{
ofstream ofs(_filename.c_str());
//不需要检查,因为打开失败会直接抛异常
ofs << info._ip << " " << info._port << " ";
//文本写的时候要注意分割符
ofs << info._d;
}
void ReadText(ServerInfo& info)//文本读
{
ifstream ifs(_filename.c_str());
ifs >> info._ip >> info._port;
//重载流提取就可以使用下面的了
//ifs >> info._d;
}
private:
string _filename;//只需要记录文件的名字即可
};
//二进制文件,尽量二进制保存
//有一些字符是常规文本保存不了的,二进制能更好的保存
//图片就是二进制文件
int main()
{
//ServerInfo info = { "127.0.0.1", 80 };
//ConfigManager cm("config.bin");
//cm.WriteBin(info);
//cm.ReadBin(info);
//cout << info._ip << ":" << info._port << endl;
//ServerInfo winfo = { "127.0.0.1", 80 };
//ConfigManager cm("config.txt");
//cm.WriteText(winfo);
//ServerInfo rinfo;
//cm.ReadText(rinfo);
//cout << rinfo._ip << rinfo._port << endl;
return 0;
}
4. stringstream的简单介绍
struct PersonInfo
{
string _name;
int _age;
Date _d;
};
ostringstream& operator<<(ostringstream& oss, Date& d)//记得加友元
{
oss << d._year << " " << d._month << " " << d._day << endl;
return oss;
}
int main()
{
// 序列化
PersonInfo info = {"张三", 18};//将这个结构的信息转化为字符串,C语言用sscanf
ostringstream oss;
oss << info._name <<" "<< info._age <<" ";
oss << info._d;
string str = oss.str();// 持续输入的东西转化为字符串
// 反序列化
istringstream iss(str);
string name;
int age;
iss >> name >> age;
//在监视中可以看到name和age的值
return 0;
}
// 网络编程中
// 我发送的信息,包含:名字,时间,内容,,,
// 我发过去的都是字节流,都需要将其转化为字符串,然后才能看