fstream::write 和 fstream::read 改变读写指针
fstream::write and fstream::read changing both reading and writing pointers
我正在学习如何在文件上写入记录并读取它。
我创建了一个名为 student
的 class,class 具有 enterStudent
、showStudent
、printInsideFile
(学生信息)等功能,.... ..
当我尝试将学生信息写入文件时,它起作用了。
当我尝试从文件中读取所有学生信息时,它有效
当我尝试同时执行这两项操作时,发生了意想不到的事情(没有显示)
我以为是 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 and istream::read 的代码,它们是高级的,所以如果有人检查 link 并告诉我们为什么
注意,当读取指针指向文件末尾时,它不会打印任何内容
考虑到我对 std::ios::app 的经验最少,我很想知道它到底是如何工作的。
我做了以下 MCVE on coliru ,(我相信)按照 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);
是必要的。
很明显,前面的write好像碰到了write head(当然)还有read head。
我在使用 std::istream::tellg() 检索正确的读取头位置时遇到了一些麻烦。
它在第一个文件输出之后而不是之前返回预期值。
我的最后一招是 file.seekg(0, std::fstream::end);
在写入任何内容之前将读取头移动到文件末尾。
对于示例中完全没有任何错误检查,我深表歉意。
当然,这必须在认真的应用程序中添加。
我将其保留下来是为了尽可能减少示例代码。
此外,我没有将错误处理视为 OP 示例代码中的问题。
我正在学习如何在文件上写入记录并读取它。
我创建了一个名为 student
的 class,class 具有 enterStudent
、showStudent
、printInsideFile
(学生信息)等功能,.... ..
当我尝试将学生信息写入文件时,它起作用了。
当我尝试从文件中读取所有学生信息时,它有效
当我尝试同时执行这两项操作时,发生了意想不到的事情(没有显示)
我以为是 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 and istream::read 的代码,它们是高级的,所以如果有人检查 link 并告诉我们为什么
注意,当读取指针指向文件末尾时,它不会打印任何内容
考虑到我对 std::ios::app 的经验最少,我很想知道它到底是如何工作的。
我做了以下 MCVE on coliru ,(我相信)按照 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);
是必要的。
很明显,前面的write好像碰到了write head(当然)还有read head。我在使用 std::istream::tellg() 检索正确的读取头位置时遇到了一些麻烦。 它在第一个文件输出之后而不是之前返回预期值。
我的最后一招是file.seekg(0, std::fstream::end);
在写入任何内容之前将读取头移动到文件末尾。对于示例中完全没有任何错误检查,我深表歉意。
当然,这必须在认真的应用程序中添加。
我将其保留下来是为了尽可能减少示例代码。
此外,我没有将错误处理视为 OP 示例代码中的问题。