文件流
C++標準庫頭文件—#include<fstream>,包含:ofstream,ifstream,fstream
open打開文件,close關閉文件
主要注意的是同個文件可同時被打開多次,但是不可以在同個作用域內同時進行IO處理,所以在函數內打開文件並對它處理的時候,記得在最後關閉文件。
ios::in 從文件讀取信息
ios::out 向文件寫入信息
ios::app 所有寫入都追加到文件末尾
ios::trunc 清空文件後打開文件
讀取文件內容一般使用getchar讀取一個字母和getline讀取一行字符串
eof()函數的判斷文件指針是否在最後,故配合eof()可以進行對文件行數的統計等
fstream file(filename,ios::out);
string s;
int row=0;//行數
while(!file.eof())
{
getline(file,line);
row++;
}
切記勿直接對文件處理,而是把文件的數據先存儲到計算機中,再對計算機內的容器進行操作。
例如:在學生信息管理系統中需要定義個student的類,我們就可以定義一個vector<student>的數組存儲它;while循環中每次getline一個字符串string後,對字符串進行遍歷,巧妙對空格進行判斷,讓對應的子串賦值給對應的數據,記的留類變量的接口。
friend void read(string filename, vector<student>& a)//文本讀出
{
fstream file(filename, ios::in);
string line;
getline(file, line);//先讀取文件最頂行的說明保證它不影響數據存儲
while (!file.eof())
{
student* temp = new student;
string str = "", s[10];
int num = 0;
getline(file, line, '\n');
for (int i = 0; i < line.size(); i++)
{
if ((line[i] == ' ' || line[i] == '\t') && str != "") {
s[num] = str;
num++;
str = "";
}
else if (line[i] != ' ' && line[i] != '\t')
str += line[i];
}
s[num] = str;
if (s[0] != "" && s[1] != "" && s[2] != "" && s[3] != "" && s[4] != "" && s[5] != "" && s[6] != "")
{
temp->SetInformation(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);//學號 姓名 性別 年齡 班級 專業 系別
a.push_back(*temp);
}
delete temp;
}
file.close();
}
//把修改好的學生信息內容,從vector容器中入讀文本,向文本寫入
friend void wirte(string filename, vector<student>a)
{
fstream file(filename, ios::out | ios_base::trunc);
file << std::right << "學號" << setw(10) << "姓名" << setw(10) << "性別" << setw(10) << "年齡" << setw(10) << "班級"
<< setw(10) << "專業" << setw(10) << "系別" << endl;
for (int i = 0; i < a.size(); i++)
{
file << a[i].GetId() << setw(10) << a[i].GetName() << setw(10) << a[i].GetSex() << setw(10)
<< a[i].GetAge() << setw(10) << a[i].GetClubm() << setw(10) << a[i].GetMajor()
<< setw(10) << a[i].GetDepartment() << endl;
}
file.close();
}
在對學生信息進行操作管理,
添加,new一個student,最後push_back;
friend void input(vector<student>& a)
{
cout << "請輸入學生的學號、姓名、性別(male or female)、年齡、班級、專業、系別(請用空格隔開每個輸入)" << endl;
student* temp = new student;
string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
temp->SetID(mId); temp->SetName(mName); temp->SetSex(mSex);
temp->SetAge(mAge); temp->SetMajor(mMajor); temp->SetDepartment(mDepartment);
a.push_back(*temp);
delete temp;
cout <<setw(12)<< "添加成功" << endl;
}
刪除,先找到要刪除的學生,從這個刪除的學生開始,讓前一名學生等於後一名學生,最後resize讓數組的長度減1;
friend void remove(vector<student>&a, int row)//刪除
{
int msize = a.size();
for (int i = row - 1; i < msize-1; i++)
a[i] = a[i + 1];
a.resize(msize - 1);
cout << setw(10) << "刪除成功" << endl;
}
修改,先找到要修改的學生,直接對學生信息進行修改,若修改的函數爲爲友元函數,需要定義SetValie()和GetValue()的接口
friend void modify(vector<student>& a, int row)//修改
{
cout << "修改人員的完整信息:姓名、性別(male or female)、類別、系別、專業、職稱(請用空格隔開每個輸入)" << endl;
string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
a[row-1].SetID(mId); a[row - 1].SetName(mName); a[row - 1].SetSex(mSex);
a[row - 1].SetAge(mAge); a[row - 1].SetMajor(mMajor); a[row - 1].SetDepartment(mDepartment);
cout << "修改成功" << endl;
}
個人查詢:直接暴力匹配關鍵詞key就行這裏就不演示了
統計:利用map<string,int>統計可以,種類就等於map對應的size(),分別輸出的話直接for遍歷即可,
friend void stat_sex(vector<student>a)//性別統計
{
map<string, int>num_sex;
for (int i = 0; i < a.size(); i++)
num_sex[a[i].GetSex()]++;
for (auto it : num_sex)
cout << setw(10) << it.first << ":" << it.second << endl;
}
完整源碼無bug如下
// I am so vegetable
//made by HRdate,2020-6-29
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<string>
#include<iomanip>
#include<set>
#include<map>
#include<conio.h>
using namespace std;
#define endl '\n'
class student
{
public:
//構造函數
student() {};
student(string mid, string mname, string msex, string mage, string mclubm, string mmajor, string mdepartment)
{
id = mid, name = mname, sex = msex, age = mage, clubm = mclubm, major = mmajor, department = mdepartment;
}
//析構函數
~student() {};
//大接口,便於在類外初始化修改類對象的私有變量
void SetInformation(string mid, string mname, string msex, string mage, string mclubm, string mmajor, string mdepartment)
{
id = mid, name = mname, sex = msex, age = mage, clubm = mclubm, major = mmajor, department = mdepartment;
}
//小接口,獲取
string GetId() { return id; }
string GetName() { return name; }
string GetSex() { return sex; }
string GetAge() { return age; }
string GetClubm() { return clubm; }
string GetMajor() { return major; }
string GetDepartment() { return department; }
//小接口,賦值
void SetID(string mId) { id = mId; }
void SetName(string mName) { name = mName; }
void SetSex(string mSex) { sex = mSex; }
void SetAge(string mAge) { age = mAge; }
void SetClubm(string mClubm) { clubm = mClubm; }
void SetMajor(string mMajor) { major = mMajor; }
void SetDepartment(string mDepartment) { department = mDepartment; }
//把文本中的數據轉化爲字符串,通過對字符串空格的處理,使得相應的數據通過SetInformation類接口賦值給vector<student>中的對應的變量
friend void read(string filename, vector<student>& a)
{
fstream file(filename, ios::in | ios::out);
string line;
getline(file, line);
while (!file.eof())
{
student temp;
string str = "", s[10];
int num = 0;
getline(file, line);
for (int i = 0; i < line.size(); i++)
{
if ((line[i] == ' ' || line[i] == '\t') && str != "") {
s[num] = str;
num++;
str = "";
}
else if (line[i] != ' ' && line[i] != '\t')
str += line[i];
}
s[num] = str;
if (s[0] != "" && s[1] != "" && s[2] != "" && s[3] != "" && s[4] != "" && s[5] != "" && s[6] != "")
{
temp.SetInformation(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
a.push_back(temp);
}
}
file.close();
}
//把修改好的學生信息內容,從vector容器中入讀文本,向文本寫入
friend void write(string filename, vector<student>a)
{
fstream file(filename, ios::out | ios_base::trunc);
file << "學號"<<'\t'<< "姓名" << '\t' << "性別" << '\t' << "年齡" << '\t' << "班級"
<< '\t' << '\t' << "專業" << '\t' << '\t' << "系別" << endl;
for (int i = 0; i < a.size(); i++)
{
file << a[i].GetId() << '\t' << a[i].GetName() << '\t' << a[i].GetSex() << '\t'
<< a[i].GetAge() << '\t' << a[i].GetClubm() << '\t' << '\t' << a[i].GetMajor()
<< '\t' << '\t' << a[i].GetDepartment() << endl;
}
file.close();
}
//輸出顯示選定的人員信息
friend void display(vector<student>a)
{
cout << "學號" << '\t' << "姓名" << '\t' << "性別" << '\t' << "年齡" << '\t' << "班級"
<< '\t' << '\t' << "專業" << '\t' << '\t' << "系別" << endl;
for (int i = 0; i < a.size(); i++)
{
cout << a[i].GetId() << '\t' << a[i].GetName() << '\t' << a[i].GetSex() << '\t'
<< a[i].GetAge() << '\t' << a[i].GetClubm() << '\t' << '\t' << a[i].GetMajor()
<< '\t' << '\t' << a[i].GetDepartment() << endl;
}
}
// I am so vegetable
//made by HRdate,2020-6-29
//錄入一個學生的信息,new一個student對象,通過SetID等接口可在類外直接定義修改private的成員變量,最後push_back進原容器vector中
friend void input(vector<student>& a)
{
cout << "請輸入學生的完整信息:學號、姓名、性別(男 or 女)、年齡、班級、專業、系別(請用空格隔開每個輸入)" << endl;
student temp;
string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
temp.SetID(mId), temp.SetName(mName), temp.SetSex(mSex), temp.SetAge(mAge);
temp.SetClubm(mClubm); temp.SetMajor(mMajor); temp.SetDepartment(mDepartment);
a.push_back(temp);
cout << '\t' << '\t' << "添加成功" << endl;
}
//刪除指定學生的信息,從這指定的學生開始,讓後一個student賦值給前一個student,往前疊加,最後resize修改一下vector容器大小
friend void remove(vector<student>&a, int row)//刪除
{
int msize = a.size();
for (int i = row ; i < msize-1; i++)
a[i] = a[i + 1];
a.resize(msize - 1);
cout << '\t' << '\t' << "刪除成功" << endl;
}
//修改指定學生的信息
friend void modify(vector<student>& a, int row)
{
cout << "修改學生的完整信息:學號、姓名、性別(男 or 女)、年齡、班級、專業、系別(請用空格隔開每個輸入)" << endl;
string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
a[row].SetID(mId); a[row].SetName(mName); a[row].SetSex(mSex); a[row].SetAge(mAge);
a[row ].SetClubm(mClubm);a[row ].SetMajor(mMajor); a[row ].SetDepartment(mDepartment);
cout << "修改成功" << endl;
}
//根據學號查詢個人
friend int find_id(string key_id, vector<student>a)
{
for (int i = 0; i < a.size(); i++)
if (a[i].GetId() == key_id)
return i;
}
//根據姓名查詢個人
friend int find_name(string key_name, vector<student>a)
{
for (int i = 0; i < a.size(); i++)
if (a[i].GetName() == key_name)
return i ;
}
//根據性別查詢
friend void find_key_sex(string key_sex, vector<student>a, vector<student>& b)
{
b.clear();
for (int i = 0; i < a.size(); i++)
{
if (a[i].GetSex() == key_sex)
b.push_back(a[i]);
}
//cout << key_sex << "查詢成功" << endl;
}
//根據班級查詢
friend void find_key_clubm(string key_clubm, vector<student>a, vector<student>& b)
{
b.clear();
for (int i = 0; i < a.size(); i++)
{
if (a[i].GetClubm() == key_clubm)
b.push_back(a[i]);
}
//cout << key_clubm << "查詢成功" << endl;
}
//性別統計
friend void stat_sex(vector<student>a)
{
map<string, int>num_sex;
for (int i = 0; i < a.size(); i++)
num_sex[a[i].GetSex()]++;
for (auto it : num_sex)
cout << setw(10) << it.first << ":" << it.second << endl;
}
//班號統計
friend void stat_clubm(vector<student>a)
{
map<string, int>num_clubm;
for (int i = 0; i < a.size(); i++)
num_clubm[a[i].GetClubm()]++;
for (auto it : num_clubm)
cout << setw(10) << it.first << ":" << it.second << endl;
}
//年齡統計
friend void stat_age(vector<student>a)
{
map<string, int>num_age;
for (int i = 0; i < a.size(); i++)
num_age[a[i].GetAge()]++;
for (auto it : num_age)
cout << setw(10) << it.first << ":" << it.second << endl;
}
//系別統計
friend void stat_department(vector<student>a)
{
map<string, int>num_department;
for (int i = 0; i < a.size(); i++)
num_department[a[i].GetDepartment()]++;
for (auto it : num_department)
cout << setw(10) << it.first << ":" << it.second << endl;
}
private:
string id, name, sex, age, clubm, major, department;//學號 姓名 性別 年齡 班級 專業 系別
};
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
string filename = "E:\\text2.txt";//文件名
fstream file(filename, ios::in | ios::out);
if (!file) {
cout << "打開文件失敗,請重新輸入。" << endl;
return 0;
}
else {
cout << "打開文件成功。" << endl;
}
vector<student>a, b;//vector不定數組存儲數據
read(filename, a);
while (1)
{
int check = 0;//菜單選擇步驟
string key;//查詢關鍵詞
for (int i = 0; i < 70; i++)
cout << '*';
cout << endl;
cout << "*" << setw(32) << "菜單" <<setw(37)<< "*" << endl;
cout << "*" << setw(40) << "輸入0:退出系統保存" <<setw(29)<<"*" << endl;
cout << "*" << setw(40) << "輸入1:顯示當前文本" << setw(29) << "*" << endl;
cout << "*" << setw(40) << "輸入2:刪除學生信息" << setw(29) << "*" << endl;
cout << "*" << setw(40) << "輸入3:修改學生信息" << setw(29) << "*" << endl;
cout << "*" << setw(40) << "輸入4:查詢個人信息" << setw(29) << "*" << endl;
cout << "*" << setw(40) << "輸入5:查詢學生信息" << setw(29) << "*" << endl;
cout << "*" << setw(40) << "輸入6:統計學生信息" << setw(29) << "*" << endl;
cout << "*" << setw(40) << "輸入7:添加學生信息" << setw(29) << "*" << endl;
for (int i = 0; i < 70; i++)
cout << '*';
cout << endl;
cin >> check;
if (check == 0)//退出系統保存
break;
else if (check == 1) {//顯示當前文本
display(a);
}
else if (check == 2) //刪除學生信息
{
cout << "1:按學號找到刪除單個學生信息" << endl << "2:按姓名找到刪除單個學生信息" << " (輸入0:退出)" << endl;
cin >> check;
if (check == 1)
{
cout << "請輸入刪除單個學生的學號:" << endl;
cin >> key;
remove(a, find_id(key, a));
}
else if (check == 2) {
cout << "請輸入刪除單個學生的姓名:" << endl;
cin >> key;
remove(a, find_name(key, a));
}
}
else if (check == 3)//修改學生信息
{
cout << "1:按學號找到修改單個學生信息" << endl << "2:按姓名找到修改單個學生信息" << " (輸入0:退出)" << endl;
cin >> check;
if (check == 1)
{
cout << "請輸入修改單個學生的學號:" << endl;
cin >> key;
modify(a, find_id(key, a));
}
else if (check == 2) {
cout << "請輸入修改單個學生的姓名:" << endl;
cin >> key;
modify(a, find_name(key, a));
}
}
else if (check == 4)//查詢個人信息
{
cout << "1:按學號查詢單個學生信息" << endl << "2:按姓名找到查詢單個學生信息" << " (輸入0:退出)" << endl;
cin >> check;
if (check == 1)
{
cout << "請輸入查詢單個學生的學號:" << endl;
cin >> key;
vector<student>c;
c.push_back(a[find_id(key, a) - 1]);
display(c);
}
else if (check == 2) {
cout << "請輸入查詢單個學生的姓名:" << endl;
cin >> key;
vector<student>c;
c.push_back(a[find_name(key, a) - 1]);
display(c);
}
}
else if (check == 5)//查詢學生信息
{
cout << "1:按性別查詢學生信息" << endl << "2:按班號查詢學生信息" << " (輸入0:退出)" << endl;
cin >> check;
if (check == 1)
{
cout << "請輸入查詢學生的性別:" << endl;
cin >> key;
vector<student>c;
find_key_sex(key, a, c);
display(c);
}
else if (check == 2)
{
cout << "請輸入查詢學生的班號:" << endl;
cin >> key;
vector<student>c;
find_key_clubm(key, a, c);
display(c);
}
}
else if (check == 6)//統計學生信息
{
cout << "1:按性別統計學生人數" << endl << "2:按班別統計學生人數" << endl << "3:按年齡統計學生人數" << endl
<< "4:按系別統計學生人數" <<endl<< " (輸入0:退出)" << endl;
cin >> check;
if (check == 1)
{
stat_sex(a);
}
else if (check == 2)
{
stat_clubm(a);
}
else if (check == 3)
{
stat_age(a);
}
else if (check == 4)
{
stat_department(a);
}
}
else if (check == 7)//添加學生信息
{
input(a);
}
//getchar();
// system("cls"); 清屏
}
write(filename, a);
file.close();
return 0;
}