C++ 文件流操作

一.文件流

在文件流中, 定义的类型有:

fstream既可以是输入流也可以是输出流
ifstream输入流
ofstream输出流

在对文件进行操作前,需要以open的形式打开,第一个参数是filename, 第二个参数是mode

mode含义
ios::in读方式
ios::out写方式
ios::app一般结合写方式,在文末尾进行追加
ios::ate一般结合读方式,指针跳到末尾
ios::trunc以截断方式打开,也就是将文件长度变为0

注意:
1.当定义 ifstream 时, 默认以 ios::in 打开;
2.当定义 ofstream 时, 默认以 ios::out|ios::trunc 打开;

  • 向文本中写数据
//尝试向文本中写数据
void Write() {
	
	ofstream fout;
	fout.open("data.txt", ios::out|ios::trunc);//即使不写,ofstream生成的默认mode也是ios::|ios::trunc
	fout << "name:wk" << " age:21" << endl;

	ofstream fout2;
	fout2.open("data.txt", ios::app);
	fout2 << "name:wwx" << " age:23" << endl;

	fout.close();
	fout2.close();
}

  • 文本中读取数据

文本中读取数据方式总结:
1.按行读取:
使用.getline()函数,遇到’\n’自动转换为’\0’, 且读取到EOF时终止返回NULL

//文本中读数据 一行一行的读
void ReadByLine() {
	ifstream fin;
	fin.open("data.txt", ios::in);//即使不写,默认的mode也是ios::in
	char buffer[1000];
	while (fin.getline(buffer, sizeof(buffer))) {//文档中有EOF结束符,当getline读到EOF(结束符)时返回NULL
		cout << buffer << endl;
	}

	fin.close();
}

2.按单词读取:
使用>>流读取,流读取的过程中遇到空白时会结束,读取到EOF时返回NULL

//文本中读数据 一个单词一个单词的读
void ReadByWord() {
	ifstream fin;
	fin.open("data.txt", ios::in);
	char word[100];
	while (fin >> word) {//注意在使用流操作的过程中流会自动忽略空白部分
		cout << word << endl;
	}

	fin.close();
}

3.按字符读取:
使用.get()函数读取,get函数除了EOF之外的字符都会进行读取。

//文本中读数据 一个字符一个字符的读
void ReadByChar() {
	ifstream fin;
	fin.open("data.txt", ios::in);
	char ch;
	while (fin.get(ch)) {//get函数会将所有字符(除了终止符EOF),全部读取
		cout << ch;
	}

	fin.close();
}

二.流状态位

流状态位含义
goodbit流状态正常时为1
failbit流状态发生可挽回的错误,如读取到EOF字符等进行置位
badbit当流发生不可挽回的错误时进行置位
eofbit当读取到终止符EOF时进行置位

注意:当在读取到EOF将eofbit进行置位时,failbit也会进行置位

template <typename T>
void showState(T& ss) {
	cout << "goodbit:" << ss.good() << endl;
	cout << "failbit:" << ss.fail() << endl;
	cout << "eofbit:" << ss.eof() << endl;
	cout << "badbit:" << ss.bad() << endl;

}

另外 clear函数可以将已经发生损坏了 的流进行恢复。


三.指针偏移

1.seekg 与 tellg:
这两个函数都是针对于输入流的操作
seekg函数官方解释为:

basic_istream& seekg( pos_type pos );

表示从ios::beg,也就是开始的位置往后偏移pos个单位

basic_istream& seekg( off_type off, std::ios_base::seekdir dir);

off:为偏移量,为正时表示向后偏移,为负时表示向前偏移
dir:为起始位置,分为 ios::beg ios::cur ios::end 三种

tellg函数官方解释为:

pos_type tellg();

表示返回目前流指针的位置,注意是输入流的指针,当读取失败时返回-1
如下为测试用例:

//测试seekg与tellg,在已经读到流末尾不进行clear的情况
void test1() {
	istringstream iss("hello World");
	cout << "tellg:" << iss.tellg() << endl;
	string s;
	iss >> s;
	cout << "s:" << s << endl;
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);
	cout << "-----------------------------------------" << endl;

	iss >> s;
	cout << "s:" << s << endl;//此时因为已经读到了EOF,eofbit 和 failbit都已经置位,tellg读取失败会返回-1
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);
	

}


//测试seekg与tellg,当流读到末尾进行clear的情况
void test2() {
	istringstream iss("hello World");
	cout << "tellg:" << iss.tellg() << endl;
	string s;
	iss >> s;
	cout << "s:" << s << endl;
	cout << "tellg:" << iss.tellg() << endl;
	cout << "-----------------------------------------" << endl;

	iss >> s;
	iss.clear();//注意这里clear的作用是将各个bit位复原
	cout << "s:" << s << endl;
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);
	cout << "-----------------------------------------" << endl;

	iss.seekg(0);
	//iss.seekg(3, ios::beg);//可以随意操作seekg最流指针的偏移进行操作
	cout << "tellg:" << iss.tellg() << endl;
	showState(iss);

}

tellp与seekp: seekp的官方文档:
basic_ostream& seekp( pos_type pos );
basic_ostream& seekp( off_type off, std::ios_base::seekdir dir );

tellp的官方文档:

pos_type tellp();

这两个的使用原理与seekg 与 putg相似,就不再做过多阐述

测试用例如下:

//测试 seekp 与 tellp
void test3() {
	ostringstream oss;
	string s("Hello World");
	oss << s;
	cout << "tellp:" << oss.tellp() << endl;
	showState(oss);
	cout << "-----------------------------------------" << endl;

	oss.seekp(0, ios::end);
	cout << "tellp:" << oss.tellp() << endl;
	showState(oss);
	cout << "-----------------------------------------" << endl;

}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言源代码的图书管理系统 #include<iostream.h> #include<fstream.H> #include<stdlib.h> #include<string.h> struct bookData { int booknumber; char bookname[30]; int store; }; struct Person { char name[20]; char studynumber[10]; int count; bookData Rbook[2]; //bookData Rbook; }; class History { public: History(fstream& a){readerbook=a;} void writehistory(); void readhistory(fstream&); private: fstream readerbook; }; class Liberian; void Find(fstream&); void CreateTxt(fstream&); class Reader { friend Liberian; public: Reader(fstream&); void print(); void handlebook(fstream&); void change(); bool findreader(); void Addreader(); void deletereader(); private: fstream file; Person person; }; class Liberian { public: Liberian(char *,char *); void changeReader(Reader&); void selfprint(); void Append(fstream&); private: char workname[20]; char worknumber[20]; }; int main() { fstream bookRecord(" book.dat",ios::in| ios::out); if(!bookRecord) { cerr<<" Can't open,try again!"<<endl; exit(1); } fstream readerRecord("reader.dat",ios::in|ios::out); if(!readerRecord) { cerr<<" Can't open,try again!"<<endl; exit(1); } int choice; int key; Reader reader(readerRecord);//读者管理系统 Liberian liberian("李天","123456");//图书管理员 History rec(readerRecord);//声明显示历史记录类 while(1) { cout<<" 请输入您的选择:\n\n" <<"1--图书管理员\n" <<"2--读者系统\n" <<"0--结束程序\n"; cin>>choice; switch(choice) { case 1: { cout<<" Hello,图书管理员:\n"; liberian.selfprint();cout<<endl; cout<<"1-- 增加新图书\n" <<"2-- 改变读者的属性\n" <<"3-- 显示历史记录\n" <<"0-- 返回\n"; cin>>key; switch(key) { case 1: liberian.Append(bookRecord); break; case 2: liberian.changeReader(reader); break; case 3: rec.readhistory(readerRecord); case 0: break ; } } break; case 2: { cout<<"学生读者\n"; int iflag=1; //reader.findreader(); cout<<"1-- 借书与还书信息\n" <<"2-- 修改个人信息\n" <<"0-- 返回\n"; cin>>key; switch(key) { case 1: reader.handlebook(bookRecord); break; case 2: reader.change(); break; case 0: break; } } break; default: return 0; } } return 0; } //增加书籍 void Liberian::Append(fstream& storef) { bookData book; int choice; int key; int num; storef.seekp(0,ios::end); int posEnd=storef.tellp(); cout<<"*************书籍入库***************"<<endl; while(1) { cout<<" Please enter your choice:"<<endl; cout<<"1--添加新书\n"<<"2--已有书籍\n"<<"0--返回\n"; cin>>choice; switch(choice) { case 1: cout<<" 书号, 书名, 数量?"<<endl; cin>>book.booknumber>>book.bookname>>book.store; storef.write(reinterpret_cast<char*>(&book),sizeof(bookData)); break; case 2: storef.seekg(0,ios::beg); cout<<"Booknumber?\n"; cin>>key; do{ storef.read(reinterpret_cast<char*>(&book),sizeof(bookData)); }while(book.booknumber!=key&&storef.tellg()!=posEnd); if(book.booknumber==key) { cout<<book.booknumber<<"----"<<book.bookname<<"----"<<book.store<<endl; cout<<" 输入已有书增加的数量:"<<endl; cin>>num; if(num>0) book.store+=num; else { cout<<" Invalid input"<<endl; } storef.seekp(-long(sizeof(bookData)),ios::cur);//////////////////// storef.write(reinterpret_cast<char*>(&book),sizeof(bookData)); cout<<"现在书籍: "<<book.bookname<<" 余量为: "<<book.store<<endl; } else cout<<"找不到此书,请重新查阅书号是否正确!"<<endl; break; case 0: return ; } } } //书籍查询 void Find(fstream & f) { bookData book; int key; int choice; f.seekg(0,ios::end); int posEnd=f.tellp(); cout<<"*************书籍查询***************"<<endl; while(1) { cout<<" 请输入您的选择\n" <<" 1-- 检索一本书\n" <<"2-- 显示全部书籍\n" <<"0-- 返回\n"; cin>>choice; switch(choice) { case 1: f.seekg(0,ios::beg); cout<<"输入你想检索书的书号"<<endl; cin>>key; do{ f.read(reinterpret_cast<char*>(&book),sizeof(bookData)); }while(book.booknumber!=key&&f.tellg()!=posEnd); if(book.booknumber==key) cout<<book.booknumber<<"---"<<book.bookname<<"---"<<book.store<<endl; else cout<<"找不到此书,请重新确认!"<<endl; break; case 2: f.seekg(0,ios::beg); do{ f.read(reinterpret_cast<char*>(&book),sizeof(bookData)); cout<<book.booknumber<<"---"<<book.bookname<<"--"<<book.store<<endl; }while(f.tellg()!=posEnd); break; case 0: return ; } } } Reader::Reader(fstream& c) { file=c; Person person={"0","0",0,{{0,"0",0}, {0,"0",0}}}; } void Reader::print() { cout<<"Name"<<"---"<<person.name<<'\n\n'<<"studynumber---"<<person.studynumber<<'\n'; } //操作书籍?????????????????????? void Reader::handlebook(fstream &filee) { int key; int choice; bookData book; bool iflag;int num=0; filee.seekp(0,ios::end); int posEnd=filee.tellp(); while(!(iflag=findreader())) { num++; if(num>=3) return; } //cout<<person.name; while(1) { cout<<"1-- 借书\n" <<"2-- 还书\n" <<"3-- 查找一本书\n" <<"0-- 返回"<<'\n'; cin>>choice; switch(choice) { case 1: { filee.seekp(0,ios::end); int posEnd=filee.tellp(); if(person.count<=1) { cout<<" 输入你要借阅图书的书号:"<<endl; cin>>key; filee.seekg(0); do{ filee.read(reinterpret_cast<char*>(&book),sizeof(bookData)); }while(book.booknumber!=key&&filee.tellp()!=posEnd); //cout<<book.booknumber<<endl; if(book.booknumber==key) { //cout<<" 找到你想借阅的图书,成功借阅!"<<endl; if(book.store>0) { person.Rbook[person.count]=book; person.count+=1; book.store-=1; filee.seekp(-long(sizeof(bookData)),ios::cur); filee.write(reinterpret_cast<char*>(&book),sizeof(bookData)); cout<<" 找到你想借阅的图书,成功借阅!"<<endl; cout<<"书籍 :"<<book.bookname<<"剩余的本数为:"<<book.store<<endl; } else cout<<" 现在此图书已经被借完了,请耐心等待几天!"<<endl; } else cout<<" 找不到你想要的图书"<<endl; } else cout<<"你最多只能借2本\n\n"; } break; case 2: { bookData blankbook={0,"0",0}; //if(person.count>0) //{ int iflag=0; filee.seekg(0); cout<<" 输入你想要还的书的书号:"<<endl; cin>>key; for(int i=0;i<2;i++) { if(key==person.Rbook[i].booknumber) { person.Rbook[i]=blankbook; cout<<"成功归还此书!"; iflag=1; person.count--; do{ filee.read(reinterpret_cast<char*>(&book),sizeof(bookData)); }while(book.booknumber!=key&&filee.tellp()!=posEnd); if(book.booknumber==key) { book.store+=1; filee.seekp(-long(sizeof(bookData)),ios::cur); filee.write(reinterpret_cast<char*>(&book),sizeof(bookData)); cout<<"书籍 :"<<book.bookname<<"余本量为: "<<book.store<<endl; } } } if(!iflag) { cout<<" 你没有借阅那本书,请确认!"<<endl; } // } // else // cout<<"你没有借书,请重新确认!\n\n"; } break; case 3: Find(filee); break; case 0: return; } } } void Reader::change() { char newname[20]; char newnumber[10]; int choice; file.seekp(0,ios::cur); int Posend=file.tellp(); bool iflag;int num=0; while(!(iflag=findreader())) { num++; if(num>=3) return; } cout<<" 请输入你的选择!"<<endl; cout<<"1--改变名字!\n" <<"2--修改学号r\n" <<"0--返回\n"; cin>>choice; switch(choice) { case 1: cout<<"输入你的新名字!\n"; cin>>newname; strcpy(person.name,newname); break; case 2: cout<<"输入你的信学号?\n"; cin>>newnumber; strcpy(person.studynumber,newnumber); break; default: break;; } file.seekp(-long(sizeof(Person)),ios::cur); file.write(reinterpret_cast<char*>(&person),sizeof(Person)); cout<<"信息修改成功!"<<endl; } void Liberian::selfprint() { cout<<" 图书管理员 :\n" <<worknumber<<"---"<<workname<<" 为您服务!\n"; } Liberian::Liberian(char *a,char*b) { strcpy(workname,a); strcpy(worknumber,b); } void Liberian::changeReader(Reader& a) { int choice; char newname[20];char newnumber[10]; cout<<"修改读者的数据信息!\n"; cout<<"1-- 增加一个读者\n" <<"2-- 删除一个读者\n" <<"0-- 结束程序\n"; cin>>choice; switch(choice) { case 1: a.Addreader(); break; case 2: a.deletereader(); break; case 0: return; } } void Reader::Addreader() { Person temp;bookData book={0,"0",0}; file.seekp(0,ios::end); int Posend=file.tellp(); cout<<"输入你想要增加的读者的名字"<<endl; cin>>temp.name; cout<<"新读者的学号:"<<endl; cin>>temp.studynumber; temp.Rbook[1]=book; temp.Rbook[0]=book; temp.count=0; file.write(reinterpret_cast<char*>(&temp),sizeof(Person)); cout<<" 成功添加!"<<temp.name<<endl; } void Reader::deletereader() { file.seekp(0,ios::end); int Posend=file.tellp(); Person person; char name[20]; cout<<"输入要删除的读者的名字!"<<endl; cin>>name; file.seekg(0); do{ file.read(reinterpret_cast<char*>(&person),sizeof(Person)); }while(strcmp(name,person.name)&&file.tellp()!=Posend); if(!strcmp(name,person.name)) { bookData blankbook={0,"0",0}; Person guest={"0","0",0,{{0,"0",0},{0,"0",0}}}; file.seekp(-long(sizeof(Person)),ios::cur); file.write(reinterpret_cast<char*>(&guest),sizeof(Person)); cout<<"成功删除!"<<person.name<<endl; } else cout<<"查无此人!"<<endl; } bool Reader::findreader() { file.seekp(0,ios::end); int Posend=file.tellp(); char name[20]; Person guest={"0","0",0,{{0,"0",0},{0,"0",0}}}; cout<<"输入查找人的名字!"; cin>>name; file.seekg(0); do{ file.read(reinterpret_cast<char*>(&person),sizeof(Person)); }while(strcmp(name,person.name)&&file.tellp()!=Posend); if(!strcmp(name,person.name)) { cout<<"查到此人:"<<person.name<<endl; return true; } else { cout<<"找不到此人,请重新确认!"<<endl; return false; } } //借阅历史 void History::readhistory(fstream& a) { readerbook=a; char name[10]="0"; readerbook.seekp(0,ios::end); int Posend=readerbook.tellp(); Person guest; int iflag=1; cout<<" 书籍借阅信息如下:"<<endl; cout<<"姓名 学号 借书量 书籍名"<<endl; readerbook.seekg(0,ios::beg); do{ readerbook.read(reinterpret_cast<char*>(&guest),sizeof(Person)); if(strcmp(guest.Rbook[1].bookname,name) || strcmp(guest.Rbook[1].bookname,name)) { cout<<guest.name<<" "<<guest.studynumber<<" "<<guest.count<<" "; for(int i=0;i<2;i++) if(strcmp(guest.Rbook[i].bookname,name)) cout<<guest.Rbook[i].bookname; iflag=0; } }while(readerbook.tellp()!=Posend); if(iflag) cout<<"没有读者借阅图书!"<<endl; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值