通过 fstream 创建结构
Posted
技术标签:
【中文标题】通过 fstream 创建结构【英文标题】:Creating Structures via fstream 【发布时间】:2009-07-24 16:30:46 【问题描述】:C++ Primer Plus 中的一个练习是让我使用 fstream 打开一个 txt 文件并将数据输入到结构中然后输出。 txt 文件的第一行是“捐助者”的数量。我似乎遇到的问题是(我认为)当我使用“inFile >> value;”时检索数字然后通过new分配结构,它需要一个int并得到一个字符串?它是否正确?我应该做些什么不同的事情?
//ch6 p278 exercise #9
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
using namespace std;
const int SIZE = 60;
struct contributions
char name[20];
double dollars;
;
char filename[20];
string donors;
bool donated;
int main()
char filename[SIZE];
cout << "Enter name of file to scan: ";
cin >> filename;
fstream inFile;
inFile.open(filename);
if(!inFile.is_open())
cout << "Could not open the file " << filename << endl;
cout << "Program terminating.\n";
exit(EXIT_FAILURE);
inFile >> donors;
contributions * ptr = new contributions[donors];
for(int h = 0; h < donors; h++)
inFile >> ptr[h].name);
inFile >> ptr[h].dollars);
//BEGIN OUTPUT OF STRUCTURES
cout << "GRAND PATRONS:\n";
for(int i = 0; i < donors; i++)
if(ptr[i].dollars >= 10000)
cout << ptr[i].name << " donated " << ptr[i].dollars << endl;
donated = true;
if (!donated) cout << "none.\n";
donated = false;
cout << "PATRONS:\n";
for(int i=0; i < donors; i++)
if(ptr[i].dollars < 10000)
cout << ptr[i].name << " donated " << ptr[i].dollars << endl;
donated = true;
if (!donated) cout << "none.\n";
delete ptr;
return 0;
【问题讨论】:
与手头的问题分开,因为你已经使用new
的数组版本来分配ptr
,你将需要使用delete
的数组版本,比如这个:delete[] ptr;
【参考方案1】:
我应该做些什么不同的事情?
好吧,如果代码基于 C++ Primer Plus 教给您的内容,请使用不同的教科书。我不想侮辱你,但代码真的很糟糕。例如,本书是否涵盖了 std::string 类?
我会建议把它扔掉,并获得 Koenig 和 Moo(最初的 C++ 团队的两个成员)的 Accelerated C++,它将教你现代、优秀、惯用的 C++。
【讨论】:
一点也不侮辱。该代码是我自己的代码的混搭,并从书中的示例代码中提取了一些想法。它被覆盖的字符串,但我觉得好像我错过了一些东西。 Vector 也被提及,在 280 页中,它还没有提及这一点。现在看看 Accelerated C++... 原则上我支持这一点,除了许多人发现“加速 C++”的学习曲线太陡峭的事实。对于那些我推荐“C++ Primer”bay Lippman/Lajoie/Moo。 (注意:没有“Plus”,但至少坚持第 3 版,Barbara Moo 加入了团队!) 我读过 Lippmann 的“C++ Primer”,当它第一次出版时(很久以前),我认为它一直在讲最明显的事情——除了第一版,我没有读过任何东西尽管。也许我不是 C++ 教程的理想测试平台...【参考方案2】:您肯定是正确的,我假设代码无法编译?您可以将捐助者变量更改为整数。输入流被重载以使用所有内置类型,即。 bool、double、int 等。
假设下一个值是整数,以下将起作用:
int numDonors;
inFile >> numDonors;
请注意,更改为整数也是“for”循环正常工作所必需的,您当前正在将字符串与整数进行比较,没有内置/默认行为。
编辑:我还注意到,当您删除贡献者数组时:
delete ptr;
但是,这只会清除第一个动态分配的块。删除动态分配对象数组的正确方法是:
delete [] ptr;
编辑 2: 感谢您的示例,所以它无法正常工作的原因是名称是第一个和最后一个,并且流运算符“>>”在空格上中断。所以本质上发生的是您首先尝试读取名称,流仅读取第一个名称并停止。然后你尝试读取捐赠的值,这会尝试读取姓氏作为值,并且无法转换为双精度,因此它返回 0。
【讨论】:
它现在可以编译,但是当它从文件中读取数据时,它的反馈是不正确的。 如您的打印输出不正确?我需要查看输入文件的示例以提供更多帮助。 输入:4 Sam Stone 2000 Freida Flass 100500 Tammy Tubbs 5000 Rich Raptor 55000 输出:输入要扫描的文件名:9.txt 大赞助人:无。赞助人:山姆捐赠 0 捐赠 0 捐赠 0 捐赠 0【参考方案3】:donors
是一个字符串,您正在尝试将其用作数组大小:
string donors;
//...
inFile >> donors;
contributions * ptr = new contributions[donors];
您应该将 donors
设为 int。此外,通常最好使用std::vector<>
,而不是手动弄乱指向原始数组的指针。看起来像这样:
std::vector<contributions> contribs;
for (...)
contributions contrib;
// .. Some way read contrib from inFile
contribs.push_back(contrib);
【讨论】:
以上是关于通过 fstream 创建结构的主要内容,如果未能解决你的问题,请参考以下文章