为什么总是多读一个数据

fangluerxu 2011-12-20 11:09:08

/*
设置一个电话本,里面的联系人必须定义为类,从磁盘中的文件中读取联系人,格式为每行一条联系人记录,姓名和电话号码用逗号(,)分割,姓名在前。例如:“zhangsan, 4567”就是一行记录;重载>>实现这个功能。
*/

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

class Concact
{
private:
string name;
string phonenumber;
public:
friend fstream& operator >>(fstream & , Concact &); //重载>>操作符,用来从文件中读取数据到对象中
};

fstream & operator >>(fstream & is , Concact &T )
{
int i = 0, j = 0;
string temp;
getline(is, temp); //从文本中读取一行

i = temp.find(","); //找到,的位置
T.name = temp.substr(0,i ); //把,以前的内容赋值给name
j = temp.find("\n");
T.phonenumber = temp.substr(i+1,j); //剩下的赋值给phonenumber

return is;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////

int main()
{
Concact temp;
vector<Concact> Phonebook; //定义一个容器,元素为一个联系人对象

fstream archieve("abc.txt");

while(!archieve.eof())
{
archieve>>temp;
Phonebook.push_back(temp); //读取联系人到容器中
}
archieve.close();

cout<<Phonebook.size(); //打印显示总是比实际数目大1

return 0;
}


我设置了一个文件,发现每次总是多读取一个空对象,也就是说容器中元素总是比文件中的记录多一个,为什么啊?

...全文
132 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
just_swizard 2011-12-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fangluerxu 的回复:]

用了2楼(羽林郎)的方法,解决了,但是依然不明白
[/Quote]

按我的理解,原因在于getline()是读取当前的一行,但并不会移到下一行,直到下次再执行getline()。所以读完最后一行以后,while(!archieve.eof())仍然是true,因为仍然还在最后一行,程序判断并没有到文件末尾,直到下一次再执行getline()以后。
fangluerxu 2011-12-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hnuqinhuan 的回复:]

应该跟文本有关系 文件最后有一个空行
[/Quote]

没有空行
fangluerxu 2011-12-20
  • 打赏
  • 举报
回复
用了2楼(羽林郎)的方法,解决了,但是依然不明白
qscool1987 2011-12-20
  • 打赏
  • 举报
回复
代码还是很清晰的,一时也看不出来问题,建议单步一下,看看容器最后一个元素的值再作分析!
無_1024 2011-12-20
  • 打赏
  • 举报
回复
应该跟文本有关系 文件最后有一个空行
just_swizard 2011-12-20
  • 打赏
  • 举报
回复
文件最后有个空行?
fangluerxu 2011-12-20
  • 打赏
  • 举报
回复
上面的注释没有完全显示,补充一下:
/*
设置一个电话本,里面的联系人必须定义为类,从磁盘中的文件中读取联系人,格式为每行一条联系人记录,姓名和电话号码用逗号(,)分割,姓名在前。例如:“zhangsan, 4567”就是一行记录;重载>>实现这个功能。
*/
yulinlang 2011-12-20
  • 打赏
  • 举报
回复

archieve>>temp;
while(!archieve.eof())
{
Phonebook.push_back(temp); //读取联系人到容器中
archieve>>temp;
}
赵4老师 2011-12-20
  • 打赏
  • 举报
回复
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
whlie (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
whlie (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧