我有这个包含类和主函数的代码:
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
我的问题是读取和输出到控制台。
打开文件后,当前位置的指针位于第一个字节,即1
之前的1234
。
我从文件的开头寻求4,
所以我的指针应位于1234
和Avi
之间的空格之前。
现在我将下一个字符串放入我的字符串变量strRead
,
现在strRead
包含&#34; Avi&#34;并且指针应该在i
Avi
和它之后的空格之间。
现在我从现在的位置寻求6, 按我的计算,这是我通过的6个字节:
Space
3
4
Line break (return)
1
1
所以我的指针应该位于第二行之后的第二行。
我是这样的意思:
11 | 111 Beni 24
现在我得到一个字符串strRead
,我对代码strRead
的理解现在应该包含&#34; 111&#34;而是出于某种原因,它包含并稍后输出& #34; 1111&#34;
有人可以解释一下为什么它会这样运作? 第一行放置和第二行的第一个字母之间没有字符,因此它应该只计为1个字节......
答案 0 :(得分: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空格(只有一个字符)替换了其中两个。
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代表一些二进制代码。