c++ - 从 txt 文件中读取变量时构造函数无法正常工作
问题描述
我有一个关于我的构造函数无法正常工作的问题。每当我运行程序时,我的重载运算符可能无法正确执行,因为当我使用cout获得输出时,我总是得到默认的构造函数值。
我相信我的构造函数声明很好,但是我的所有对象都被0和Unknown填充
这是我的txt文件:
1 Prince Heins 25
2 Lady Bridgette 29
3 Tony Ann 223
4 Lucy Phoenix 35
这是我的代码;
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <istream>
#include <iomanip>
#include <cstring>
#include <ostream>
using namespace std;
class contact{
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact(){
this->name="Unknown";
this->surname="Unknown";
this->phonenumber="Unknown";
this->listno=0;
}
contact (string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->phonenumber=phonenumber;
}
contact(int listno,string name,string surname,string phonenumber){
this->name=name;
this->surname=surname;
this->listno=listno;
this->phonenumber=phonenumber;
}
friend ostream & operator<< (ostream &out, const contact &con){
out << con.listno << con.name << con.surname << con.phonenumber;
return out;
}
friend istream & operator>> (istream &in, contact &con){
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main(){
ifstream pbin("phoneData2.txt");
string line;
long linecount;
for(linecount=0;getline(pbin,line);linecount++);
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL){
while(pbin>>myArray[i]);
}
}
pbin.close();
cout << myArray[2]; // try attempt
return 0;
}
}
这是我的输出 cout << Array[2];
解决方案
问题是由错误使用的算法和错误放置的语句引起的。
那么,让我们看看下面发生了什么:
long linecount;
for(linecount=0;getline(pbin,line);linecount++)
;
contact* myArray = new contact[linecount];
pbin.seekg(0);
if(pbin.is_open()){
int i;
for(i=0;i<linecount;i++){
if(pbin!=NULL) {
while(pbin>>myArray[i]);
}
}
pbin.close();
你想计算行数。因此,您阅读所有行,直到eof
设置状态。但是,此外,该fail
位也将被设置。另请参见此处。
如果你使用你的调试器,你会发现一个 3 in _Mystate
.
然后你执行一个seekg
. 这将重置该eof
位但保留该fail
位。然后调试器显示
您可以看到该fail
位仍然设置。
所以,这将导致主要问题。如果您的写入if(pbin!=NULL)
肯定是错误的(在我的机器上甚至无法编译),或者如果您更好地写入if(pbin)
,则仍然会设置失败位。并且由于流的bool
and!
运算符被覆盖(请参见此处),if
and的结果while
将是错误的,并且您pbin>>myArray[i]
将永远不会被执行。
所以,apbin.clear()
会有所帮助。
但是,尽管您的类定义已经非常好,覆盖了插入器和提取器,但您并没有使用完整的 C++ 功能来读取数据。
一项基本建议是永远不要将原始指针用于拥有的内存。最好也不要new
。为您的目的使用专用容器。例如一个std::vector
。您可以将std::vector
s 构造函数5与std::istream_iterator
. 请阅读这里。的基于范围的构造函数std::vector
将从给定范围复制数据,由开始和结束迭代器表示。如果您使用std::istream_iterator
,它将调用您覆盖的提取器运算符,直到读取所有数据。
所以你的主要缩小到:
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
这看起来更紧凑,更容易阅读。我们从带有 initializer 的 if 语句开始。初始化部分定义了变量,构造函数将为我们打开文件。在条件部分,我们简单地写pbin
. 并且,如上所述,bool
将调用其操作员,以检查一切是否正常。
请注意:
- 我们不需要
close
声明,因为 的析构函数std::ifstream
会为我们关闭文件。 - 外部命名空间不会被变量名污染
pbin
。if
这就是为什么应该使用带有初始化程序的语句的原因之一。
我们已经std::vector
用它的范围构造函数描述了 。所以通过非常简单的语句来读取完整的文件很简单
std::vector data(std::istream_iterator<contact>(pbin), {});
请注意:
然后整个程序可以重写为:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
class contact {
private:
int listno;
string name;
string surname;
string phonenumber;
public:
contact() {
this->name = "Unknown";
this->surname = "Unknown";
this->phonenumber = "Unknown";
this->listno = 0;
}
contact(string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->phonenumber = phonenumber;
}
contact(int listno, string name, string surname, string phonenumber) {
this->name = name;
this->surname = surname;
this->listno = listno;
this->phonenumber = phonenumber;
}
friend ostream& operator<< (ostream& out, const contact& con) {
out << con.listno << '\t' << con.name << '\t' << con.surname << '\t' << con.phonenumber;
return out;
}
friend istream& operator>> (istream& in, contact& con) {
in >> con.listno >> con.name >> con.surname >> con.phonenumber;
return in;
}
};
int main() {
// Open source file and check, if it could be opened
if (ifstream pbin("r:\\phoneData2.txt");pbin) {
// Read complete source file
std::vector data(std::istream_iterator<contact>(pbin), {});
// Show data on console
std::copy(data.begin(), data.end(), std::ostream_iterator<contact>(std::cout, "\n"));
}
return 0;
}
推荐阅读
- html - 导航栏帮助:为什么形状出现在“家”上方而不是下方
- excel - 如何根据最后日期和唯一标准查找值
- python - 使用 OpenCV 计算玻璃碎片
- java - 将 Spring 事件侦听器添加到 Camunda BPM Run Docker
- arrays - 如何在Angular 8中使用对象模拟数组数据以进行单元测试
- c - 带有数组的斐波那契 c 程序
- python - For循环数据框python
- c# - 用选定的项目填充数据库中的下拉列表,然后按字母顺序填充其余项目
- postgresql - Postgresql 多值文本字段
- jupyter-notebook - 无法使用来自 jupyter nbcontrib_extensions 的导出器