板子出问题了,今晚又要通宵了,哎,工程重新综合完不知道啥时候去了,难受啊,还是总结一下前段时间看的标准I/O吧。顺便写了个基于文件保存信息的学生管理系统,加深一下对文件I/O的理解,还是忍不住吐槽配古董级电脑的综合工程速度。。。
目录
<sstream>的应用,类型转换
I/O三个独立的头文件:
iostream fstream sstream
1,iostream 定义了用于读写流的基本类型
istream:读流。 ostream:写流。 iostream:读写流
2,fiosrtream 定义了用于读写文件的基本类型
ifstream:读文件。ofstream:写文件。iofstream:读写文件
3,sstream 定义了用于读写内存string对象的基本类型。
istringstream:读内存string。 ostringstream:写内存string。stringstream:读写内存string
由于标准库的继承实现:ifstream 和istream可以和istream一样使用(>>,getline等)其对象和cin使用同
ofstream 和 osringstream可以和ostream一样使用(<<)其对象和cout使用同
流条件状态:流可能出错,会有一些函数调取管控流的条件状态。
流一旦发生错误后序会失败:检查流状态最好的办法是把流当做条件使用
eg:while(cin>>word)循环检查>>返回的流状态,操作成功,条件true
管理输出缓冲:每个输出流都管理一个缓冲区保存管理输出的数据
缓冲刷新条件:
1,程序正常结束,return 2,缓冲区满 3,endl显示刷新
4,ubitbuf设置缓冲状态 5,关联:cin和cerr和cout默认关联,
cin或cerr操作会刷新cout
刷新操作:cout<<"hahaha"<<endl;输出+换行,刷新
cout<<"hahaha"<<ends;输出+空格,刷新
cout<<"hahaha"<<flush;输出,刷新
cout<<unitbuf;
.......任何输出都立即刷新,没有缓冲
cout<<nounitbuf 结束,后面正常缓冲
关联输入和输出流:任何输入流都会刷新所关联的输出流,cout默认关联cin
可以将一个istream关联到一个ostream也可以两个ostream关联
cin.tie(&cout) cerr.tie(&cout) cerr.tie(cout )
i/o流基本操作:
void file_stream()
{ //input为fstream对象,用法同istream的cin
string addr_in = "D:/4kHZ_RS_data.txt";
string addr_out = "D:/8KHZ_LDPC_data.txt";
string line;
ifstream input(addr_in);
while (input >> line)
cout << line;
input.close();
ifstream input2(addr_in);
while (getline(input2, line))
cout << line << endl;
input2.close();
{
ifstream input3;
input3.open(addr_in, ofstream::in);//对象绑定文件并打开
while (getline(input3, line))
cout << line << endl;
//input3离开作用域,与之关联的文件自动关闭
}
//文件模式 in(读) out(写) app(操作前定位到文件末尾)
//ate(打开文件后立即定位到文件末尾) trunc(截断文件)
//in 只用于ifstream fstream out 只用于ofstream fstream
//只有out设定时才可以trunc
//trunc没被设定才可以app app模式下默认out
//默认情况下out模式使用trunc截断文件,要保留原文件内容app
//ifstream默认in ofstream 默认out fstream默认in&out
{
ifstream input;
ofstream output;
input.open(addr_in, ofstream::in);//对象绑定文件并打开
output.open(addr_out, ofstream::out | ofstream::trunc);
//显示截断,不写|后面默认trunc
while (getline(input, line))
output << line<<endl;//写入文件 output和cout同用法
}
//string流 sstring 内存I/O
//istringstream 从string读
//ostringstream 向string写
//stringstream 既可以向string读,也可以写
}
int main22()
{
file_stream();
return 0;
}
<sstream>的应用,类型转换
<sstream> 定义了三个类:istringstream、ostringstream 和 stringstream
<sstream> 主要用来进行数据类型转换,由于 <sstream> 使用 string 对象来代替字符数组(snprintf方式),就避免缓冲区溢出的危险。与c库的数据类型转换而言,<sstream> 更加安全、自动和直接。
string流 sstring 内存I/O
istringstream 从string读
ostringstream 向string写
stringstream 既可以向string读,也可以写
利用stringstream的输入输出特性:转换字符串和数字,判断字符串是不是数字等
stringstream基本操作:
void stringstream_opt()
{
//拼接字符串
stringstream ss;
ss << "Hellow";
ss << "World";
//cout << ss.str() << endl;//返回string对象
cout<< ss.str().size();
string temp = ss.str();//若要对str()返回的string对象进行进一步操作,先保存,否则对象会析构
temp.c_str();
//void str(const string & s);该方法是重新给stringstream赋新值,改变stream的内存变化了。
cout << ss.str() << endl;
//void clear ( iostate state = goodbit );
//该方法绝非清空stringstream中的内容,而是清空该流的错误标记!多次使用stringstream对象需要用到
ss.str("");//清除缓存
int a = 12;
char c;
ss << a;
ss >> c;
cout << c << endl;
ss.clear();//多次使用同一个ss需要清空标志位
ss << c;
ss >> a;
cout << a << endl;
}
stringstream应用(数字字符串转换,数字判定)
string NumberToString(int num)
{
stringstream ss;
string str;
ss << num;
ss >> str;
return str;
}
int StringToNumber(string strNum)
{
stringstream ss;
int num;
ss << strNum;
ss >> num;
return num;
}
//任意类型之间的转换
template<typename out_type, typename in_value>
out_type convert(const in_value & in)
{
stringstream stream;
stream << in;//向流中传值
out_type result;//这里存储转换结果
stream >> result;//向result中写入值
return result;
}
//判断是不是数字
bool isNum(string s)
{
stringstream ss(s);//输入输出流初始化s
double num_part;
char letter_part;
if (!(ss >> num_part))//ss>>num_part把string转换为double(int和float也可以),
//转换成功则返回为真,否则返回失败
return false;
if (ss >> letter_part)//上面部分将ss里面的数字部分接收,ss的数字部分清除
return false; //123f 若有非数字部分则输入到letter_part部分,返回true
return true;
}
int main()
{
cout << isNum("12345.67")<<endl;
cout << isNum("123.gg3") << endl;
string numtostr = NumberToString(123);
cout << numtostr << endl;
int strtonum = StringToNumber("123.");
cout << strtonum << endl;
cout << convert<double>("123.456");
cout << convert<string>(123.456);
stringstream_opt();
return 0;
}
基于文件的学生信息管理系统:
类:
class Score {
public:
float cpp;//c++成绩
float communication;//通信原理成绩
float english;//英语成绩
};
class Student {
public:
char num[11];//学号
int age;//年龄
char name[30];//姓名
char sex[5];//性别
Score sc;
};
class Teacher {
public:
Student stu[N]; //N为50
void seek();//查找
void modify();//修改信息
void insert();//插入学生信息
void del();//删除学生
void display();//显示学生信息
void sorts();//按学号排序
void menu();//菜单
void refresh();//刷新
};
//插入学生信息
void Teacher::insert() {
int j = n;
int m;//要增加的学生人数
cout << "请输入待增加的学生数:" << endl;
cin >> m;
do
{
Student stu;
cout << "请输入第" << j - n + 1 << "个学生的学号" << endl;//输入学生信息
cin >> stu.num;
cout << "请输入第" << j - n + 1 << "个学生的姓名" << endl;
cin >> stu.name;
cout << "请输入第" << j - n + 1 << "个学生的年龄" << endl;
cin >> stu.age;
cout << "请输入第" << j - n + 1 << "个学生的性别" << endl;
cin >> stu.sex;
cout << "请输入第" << j - n + 1 << "个学生的C++成绩" << endl;
cin >> stu.sc.cpp;
cout << "请输入第" << j - n + 1 << "个学生的通信原理成绩" << endl;
cin >> stu.sc.communication;
cout << "请输入第" << j - n + 1 << "个学生的英语成绩" << endl;
cin >> stu.sc.english;
j++;
fstream file("student.txt", ios::out | ios::binary | ios::app);
file.write((char *)&stu, sizeof(Student));//把该学生对象写入文件
file.close();
} while (j<n + m);
n += m;
cout << "信息增加完毕" << endl;
}
void Teacher::seek() {
cout << "请输入要查询的学生的学号" << endl;
char str[30];
int flag = 0;
cin >> str;
fstream file("student.txt", ios::binary | ios::in);//打开文件
while (!file.eof())
{
Student stu;
file.read((char *)&stu, sizeof(Student));
if (strcmp(stu.num, str) == 0) //判断从文件读出对象的学号信息是否和输入相等
{
flag = 1;
cout << "学生学号 学生姓名 年龄 性别 C++成绩 通信原理 大学英语成绩" << endl;
cout << stu.num << "\t " << stu.name << " \t" << stu.age << "\t" << stu.sex << "\t" << stu.sc.cpp<< " \t" << stu.sc.communication << "\t\t " << stu.sc.english << endl;
break;
}
}
if (flag != 1)
cout << "该学号不存在" << endl;
file.close();
}
void Teacher::modify() {
int item, age, score;//选择修改项,修改年龄
Student stu;
int flag;
char str[20];//暂时存修改内容
cout << "请输入要查询的学生的学号" << endl;
cin >> str;
fstream file("student.txt", ios::binary | ios::in);//打开文件存取学生对象的文件
while (!file.eof())
{
file.read((char *)&stu, sizeof(Student));//读取文件
if (strcmp(stu.num, str) == 0)//如果存在学生信息输出
{
flag = 1;
cout << "学生学号 学生姓名 年龄 性别 C++成绩 通信原理 大学英语成绩" << endl;
cout << stu.num << "\t " << stu.name << " \t" << stu.age << "\t" << stu.sex << "\t" << stu.sc.cpp << " \t" << stu.sc.communication << "\t\t " << stu.sc.english << endl;
break;
}
}
if (flag != 1)//如果不存在则提示无该学生
cout << "该学生不存在" << endl;
file.close();
cout << "------------------" << endl;
cout<<"1.修改姓名"<<endl;
cout << "2.修改年龄" << endl;
cout << "3.修改性别" << endl;
cout << "4.修改C++成绩" << endl;
cout << "5.修改通信原理成绩" << endl;
cout << "6.修改大学英语成绩" << endl;
cout << "7.退出本菜单\n");
cout << "------------------" << endl;
while (1)
{
cout << "请选择子菜单编号" << endl;
cin >> item;
switch (item)
{
case 1:
cout << "请输入新的姓名"<< endl;
cin >> str;
strcpy(stu.name, str); break;//为学生姓名赋新值
case 2:
cout << "请输入新的年龄:" << endl;
cin >> age;
stu.age = age; break;//为学生年龄赋新值
case 3:
cout << "请输入新的性别:" << endl;
cin >> str;
strcpy(stu.sex, str); break;//为学生性别赋新值
case 4:
cout << "请输入新的C++成绩:" << endl;
cin >> score;
stu.sc.cpp = score; break;//为学生成绩复新制
case 5:
cout << "请输入新的通信原理成绩:" << endl;
cin >> score;
stu.sc.communication = score; break;
case 6:
cout << "请输入新的英语成绩:" << endl;
cin >> score;
stu.sc.english = score; break;
case 7: {
fstream file("student.txt", ios::out | ios::binary | ios::app);
cout << "修改成功" << endl;
file.write((char *)&stu, sizeof(Student));//把新的学生信息写入文件
file.close();
return;
}
default:printf("请在1-7之间选择\n");
}
}
}
void Teacher::del() {
vector<Student> va;
Student stu;//将读出的学生信息存入该对象
int flag;
char str[20];
cout << "请输入要删除的学生的学号" << endl;
cin >> str;
fstream file("student.txt", ios::binary | ios::in);//打开文件存取学生对象的文件
while (!file.eof())
{
file.read((char *)&stu, sizeof(Student));//读取文件
if (strcmp(stu.num, str) == 0)//如果存在学生信息输出
{
flag = 1;
continue;
}
va.push_back(stu);//将非删除的学生存入容器
}
fstream file1("student.txt", ios::out | ios::trunc);
for (int i = 0; i<va.size(); i++)
{
file1.write((char *)&va[i], sizeof(Student));//将容器中的学生对象写入文件
}
cout << "删除成功" << endl;
file.close();//关闭文件
file1.close();
}
static bool myCompare(const Student& a1, const Student& a2)//自定义排序
{
return strcmp(a1.num, a2.num) <= 0;//按学号从小到大排序
}
void Teacher::sorts() {
vector<Student> va;
Student stu;
fstream file("student.txt", ios::binary | ios::in);//打开文件存取学生对象的文件
while (!file.eof())
{
file.read((char *)&stu, sizeof(Student));//读取文件
va.push_back(stu);//将学生对象存入容器
}
va.pop_back();
sort(va.begin(), va.end(), myCompare);//使用sort进行排序
fstream file1("student.txt", ios::out | ios::trunc);
for (int i = 0; i<va.size(); i++)
{
file1.write((char *)&va[i], sizeof(Student));//将排序好的写入文件
}
file.close();
file1.close();
}
void Teacher::refresh() {
Teacher t;
t.sorts();
t.display();
}
void Teacher::display() {
int flag;
int t = 0;
fstream file("student.txt", ios::binary | ios::in);
cout << "欢迎进入西安电子科技大学研究生通信与信息系统2班成绩查询系统" << endl;
cout << "学生学号 学生姓名 年龄 性别 C++成绩 通信原理 大学英语成绩" << endl;
while (!file.eof())
{
Student stu;
file.read((char *)&stu, sizeof(Student));//从文件读出所有学生信息
flag = 1;
cout << stu.num << "\t " << stu.name << " \t" << stu.age << "\t" << stu.sex << "\t" << stu.sc.cLauage << " \t" << stu.sc.math << "\t\t " << stu.sc.english << endl;
}
if (flag != 1)
cout << "无该学生" << endl;
file.close();
}