我有这个代码,它包含一个类和一个主函数:
class Employee {
int m_id;
string m_name;
int m_age; public:
Employee(int id, string name, int age) :m_id(id), m_name(name), m_age(age) {}
friend ostream& operator<<(ostream& os, const Employee& emp)
{
os << emp.m_id << " " << emp.m_name << " " << emp.m_age
<< endl;
return os;
}
};
int main() {
const int Emp_Num = 3;
fstream fs("dataBase.txt", ios::out);
if (!fs) {
cerr << "Failed opening file. Aborting.n";
return -1;
}
Employee* list[Emp_Num] =
{ new Employee(1234, "Avi", 34),
new Employee(11111, "Beni", 24),
new Employee(5621, "Reut", 26) };
for (int i = 0; i < Emp_Num; i++)
{
fs << (*list[i]);
delete list[i];
}
fs.close();
fs.open("dataBase.txt");
if (!fs) {
cerr << "Failed opening file. Aborting.n";
return -1;
}
fs.seekg(4);
string strRead;
fs >> strRead;
cout << strRead << endl;
fs.seekg(6, ios::cur);
fs >> strRead;
cout << strRead << endl;
fs.seekg(-9, ios::end);
fs >> strRead;
cout << strRead << endl;
}
以下是我的理解,在第一个文件打开和关闭后,文件dataBase.txt
应该是这样的:
1234 Avi 34
11111 Beni 24
5621 Reut 26
我的问题是读取和输出到控制台。打开文件后,我当前位置的指针位于第一个字节,即1234
之前的1
。
我从文件的开头查找4,所以我的指针应该在CCD_ 4和CCD_。
现在我将下一个字符串放入字符串变量CCD_ 6中,现在CCD_ 7包含";Avi";并且指针应该在CCD_ 9的CCD_
现在我从我现在的位置上寻找6,据我统计,这是我通过的6个字节:
Space
3
4
Line break (return)
1
1
所以我的指针应该在第二行,在两个第一行之后。
我的意思是:
11 | 111 Beni 24
现在我得到了strRead
的字符串,根据我对代码strRead
的理解,现在应该包含";111〃;,相反,由于某种原因,它包含并稍后输出";1111";。
有人能解释一下为什么它是这样工作的吗?第一行的drop和第二行的第一个字母之间没有字符,所以它应该只算作1个字节。。。
我做了以下测试:
我已经在一个文本为的文件上运行了您代码的第二部分(从文件中读取)
1234 Avi 34 11111 Beni 24 5621 Reut 26
因此,我用空格替换了行的末尾,并且打印到控制台的代码输出预期结果111
。然后,我开始怀疑seek
会跳过行的末尾。
然后我改了代码(没有修改文件),并以二进制模式处理文件:
//...
fstream fs("dataBase.txt", ios::out | ios::binary);
//...
fs.open("dataBase.txt", ios::in | ios::binary );
//...
结果再次达到预期:111
。
这两种情况都有什么变化
好吧,在纯文本(而不是二进制模式)中,行的末尾实际上是2个字符(这可能因其他平台而异,我在Windows上复制它):r
和n
。这就是为什么你读四个一(1111
)而不是三个(111
)。
从Avi
:后的空间计数6个位置
A v i _ 3 4 r n 1 1 1 1 1
^
1 2 3 4 5 6 7 8
在我执行的第一个测试中,一个空格(只有一个字符)替换了其中的两个字符。
A v i _ 3 4 _ 1 1 1 1 1
^
1 2 3 4 5 6 7 8
在二进制模式下,这两个字符都表示为一个单独的读取单元(我没有研究过这是否与平台有关)。
A v i _ 3 4 B 1 1 1 1 1
^
1 2 3 4 5 6 7 8
B代表一些二进制代码。