【发布时间】:2019-09-18 09:03:12
【问题描述】:
我有一些代码从 .txt 文件中获取名称列表和双精度值,并在命令提示符中显示这些值。为此,动态分配结构数组。代码应该根据 .txt 文件中的第一个值知道数组的大小,然后是名称和相关值。然后它应该将列表显示为两部分,其名称的关联双精度值大于或等于 10.000 首先列出。如果没有任何值符合条件,则在前半部分显示“无”。
程序执行,但调试器给出异常,输出不符合预期。
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
struct donor
{
string name;
double contribution = 0;
};
int main()
{
string filename;
ifstream inFile;
cout << "Enter name of data file: ";
cin >> filename;
inFile.open(filename);
cin.clear();
if(!inFile.is_open())
{
cout << "Could not open the file " << filename << endl;
cout << "Program terminating.\n";
exit(EXIT_FAILURE);
}
int amount;
inFile >> amount;
cin.clear();
donor* dlist = new donor[amount];
int i;
while(inFile.good())
{
for(i = 0; i < amount; i++)
{
getline(inFile, dlist[i].name);
cin.clear();
inFile >> dlist[i].contribution;
cin.clear();
}
}
cout << "Here's the list of Grand Patrons:\n";
bool grandpatrons = false;
for(i = 0; i < amount; i++)
{
if(dlist[i].contribution >= 10000)
{
grandpatrons = true;
cout << dlist[i].name << endl;
cout << dlist[i].contribution << endl;
}
}
if(grandpatrons == false)
{
cout << "None" << endl;
}
cout << "Here's the list of Patrons:\n";
for (i = 0; 1 < amount; i++)
{
if (dlist[i].contribution < 10000)
{
cout << dlist[i].name << endl;
cout << dlist[i].contribution << endl;
}
}
delete[] dlist;
return 0;
}
donorlist.txt 文件如下所示:
4
Bob
400
Alice
11000
但输出看起来像这样:
Enter name of data file: donorlist.txt
Here's the list of Grand Patrons:
None
Here's the list of Patrons:
0
0
0
0
调试器给我的异常是:
Exception thrown at 0x5914F3BE (ucrtbased.dll) in 6_9.exe: 0xC0000005: Access violation reading location 0xA519E363.
现在我假设从动态分配的内存中读取有问题。也许有什么东西导致我从分配的数组之外的内存中读取?我无法准确找到错误的出处。
【问题讨论】:
-
由于拼写错误,您超出了数组边界。在第二个 for 循环中,条件中有 1,应该有 i。
-
先修复输入文件,它有2个捐赠者,而不是4个。接下来修复文件读取代码,inFile >> dlist[i].contribution语句不读取行尾。所以下一个捐助者名称将是一个空字符串,程序现在注定要与文件不同步。那些是从屏幕上跳下来打我脸的虫子,可能还有更多。一定要练习使用调试器,这样你才能看到它出错了。
-
@Eugene Damnn,我看着那个。干杯。
-
@HansPassant 谢谢。我只是使用调试器一步一步地完成它,我确实看到一个空字符串被放在 getline(inFile, dlist[i].name); 行中。这难道不是由 inFile >> amount; 行引起的,因为贡献的输入出现在名称之后?我看不出它如何不读取行尾会导致上一行中的字符串输入采用空字符串。
-
iostream 需要一段时间才能停止吃你的午餐,它必须在艰苦的学校里学习。一揽子建议是始终如一地使用 getline() 。添加一些基本的错误检查以验证您没有得到空字符串。使用stringstream进行解析。
标签: c++