[英]fstream::write and fstream::read changing both reading and writing pointers
我正在学习如何在文件中写入记录并阅读它。
我创建了一个名为student
的类,该类具有enterStudent
、 showStudent
、 printInsideFile
(student info) 、......等功能。
当我尝试将学生信息写入文件时,它可以工作。
当我尝试从文件中读取所有学生信息时,它可以工作
当我尝试两者都做时,会发生一些意想不到的事情(什么都没有出现)
我认为file.flush()
的问题,所以当我删除它时,输出是不可读的文本
我可以关闭文件并再次打开它,但我认为这很愚蠢
代码是:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class student {
private:
char id[5], name[20], age[5], address[50], gender[5];
public:
void enterStudent() {
cout << "Enter student id : "; cin >> id;
cout << "\nEnter student name : "; cin >> name;
cout << "\nEnter student age : "; cin >> age;
cout << "\nEnter student address : "; cin >> address;
cout << "\nEnter student gender : "; cin >> gender;
}
void showStudent() {
cout << "#########student data##########\n";
cout << "student id : "<< id;
cout << "\nstudent name : " << name;
cout << "\nstudent age : " << age;
cout << "\nstudent address : " << address;
cout << "\nstudent gender : " << gender<<endl;
}
void printInsideFile(fstream &file) {
file.write(id,sizeof(id));
file.write(name, sizeof(name));
file.write(age, sizeof(age));
file.write(address, sizeof(address));
file.write(gender, sizeof(gender));
file.flush();
}
bool readFromFile(fstream &file) {
if (file.eof())
return 0;
file.read(id, sizeof(id));
file.read(name, sizeof(name));
file.read(age, sizeof(age));
file.read(address, sizeof(address));
file.read(gender, sizeof(gender));
if (file.eof())
return 0;
return 1;
}
void showAllFromFile(fstream &file) {
while (this->readFromFile(file))
this->showStudent();
}
};
int main() {
student s;
fstream file;
file.open("a.txt", ios::in | ios::out | ios::app);
if (!file)
goto k270;
s.enterStudent();
s.printInsideFile(file);
//when i read one student , it works okay
//s.readFromFile(file);
//s.showStudent();
//when i try to read multiple students , it doesn't work at all
s.showAllFromFile(file);
file.close();
k270:
system("pause");
return 0;
}
问题不在于 ios::app
似乎函数file.write()
和file.read()
改变了读取指针和写入指针。
即使你使用file<<"text";
或file>>array of chars;
两个指针都在变化。
我搜索了它,但没有找到解释,但我找到了ostream::write和istream::read的代码,它们是先进的,所以如果有人检查链接并告诉我们原因
请注意,当读取指针指向文件末尾时,它不会打印任何内容
考虑到我对std::ios::app的经验最少,我很想知道它是如何工作的。
我在 coliru 上做了以下 MCVE ,(我相信)它按 OP 的预期工作:
#include <fstream>
#include <iostream>
int main()
{
// open a text file
std::fstream file("test.txt", std::ios::in | std::ios::out | std::ios::app);
// remember current position of read head
file.seekg(0, std::fstream::end); // a trick to update the read head before writing anything
std::fstream::pos_type pos0 = file.tellg();
std::cout << "pos0: " << pos0 << '\n';
// write a line to end of text
std::cout << "Write a line.\n";
file << "A line written by main.cpp" << std::endl;
std::cout << "pos after writing: " << file.tellg() << '\n';
// rewind to remembered position of read head
file.seekg(pos0);
// read the last written line
{ std::string buffer; std::getline(file, buffer);
std::cout << "Last line: '" << buffer << "'\n";
}
// rewind to the beginning of file
file.seekg(0);
// read all
std::cout << "Read all:\n";
for (std::string buffer; std::getline(file, buffer);) {
std::cout << "'" << buffer << "'\n";
}
}
测试会话:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp \
&& echo -e "1st line written by echo\n2nd line written by echo\n3rd line written by echo" > test.txt \
; ./a.out
pos0: 75
Write a line.
pos after writing: 102
Last line: 'A line written by main.cpp'
Read all:
'1st line written by echo'
'2nd line written by echo'
'3rd line written by echo'
'A line written by main.cpp'
笔记:
我完全确定file.seekg(0)
在read all
读取之前需要将读取的文件头倒回到文件的开头。
我不确定read the last written line
的内容……
我发现file.seekg(pos0);
有必要的。
显然,之前的写入似乎触及了写头(当然)以及读头。
我在使用std::istream::tellg()检索正确的读取头位置时遇到了一些麻烦。 它在第一个文件输出之后而不是之前返回了预期值。
我最后的手段是file.seekg(0, std::fstream::end);
在写入任何内容之前将读取头移动到文件末尾。
对于示例中完全没有任何错误检查,我深表歉意。
当然,这必须在严肃的应用程序中添加。
我省略了它以使示例代码尽可能少。
此外,我不认为错误处理是 OP 示例代码中的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.