tags:

views:

105

answers:

3

One of the exercises in C++ Primer Plus is having me use fstream to open a txt file and input data into a structure then output it. First line of the txt file is the number of "donors". The problem I seem to be having is that (I think) when I use "inFile >> value;" to retrieve the number and then allocate the structure via new, its expecting an int and its getting a string? Is this correct? What should I be doing differently?

//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;
}
+1  A: 

You are most certainly correct, I assume the code does not compile? You can just change the donors variable to an integer. The input streams are overloaded to work with all built in types, ie. bool, double, int etc.

The following will work, assuming the next value is an integer:

int numDonors;
inFile >> numDonors;

Note that the change to an integer is also necessary for the 'for' loops to work correctly, you are currently comparing a string to an integer, there is no built-in/default behavior for this.

Edit: I also noticed that when you delete your array of contributors you do:

delete ptr;

However, this will only clear out the first dynamically allocated block. The correct way to delete an array of dynamically allocated objects is:

delete [] ptr;

Edit 2: Thanks for the sample, so the reason it is not working correctly is the fact that the names are first and last, and the stream operator '>>' breaks on whitespace. So what is essentially happening is you first attempt to read the name, the stream reads the first name only and stops. Then you try to read the donated value, this attempts to read the last name as the value and cannot convert to an double so it returns 0.

DeusAduro
It compiles now but when it reads the data from the file what its giving back is not correct.
scribbles
As in your printed output is incorrect? I would need to see a sample of the input file to help more.
DeusAduro
INPUT:4Sam Stone2000Freida Flass100500Tammy Tubbs5000Rich Raptor55000OUTPUT:Enter name of file to scan: 9.txtGRAND PATRONS:none.PATRONS:Sam donated 0 donated 0 donated 0 donated 0
scribbles
A: 

donors is a string, and you are trying to use it as an array size:

string donors;
//...

inFile >> donors;
contributions * ptr = new contributions[donors];

You should make donors an int. Also it's usually better to use std::vector<> instead of manually messing with pointers to raw arrays. That would look something like this:

std::vector<contributions> contribs;
for (...) {
  contributions contrib;
  // .. Some way read contrib from inFile
  contribs.push_back(contrib);
}
sth
+2  A: 

What should I be doing differently?

Well, if the code is based on what C++ Primer Plus has taught you - use a different text book. I don't want to insult you, but the code is really poor. For example, has the book covered the std::string class?

I would recommend junking it, and getting Accelerated C++ by Koenig & Moo (two of the original C++ team) which will teach you modern, good, idiomatic C++.

anon
Not insulted at all. The code is a mash of my own code and pulling ideas from sample code in the book. It's covered string but I feel as if I'm missing something. Vector has also been mentioned, 280 pages in and it has yet to mention this. Looking at Accelerated C++ now...
scribbles
In principle I second this, except for the fact that many find that "Accelerated C++" has too steep a learning curve. For those I recommend "C++ Primer" bay Lippman/Lajoie/Moo. (Note: no "Plus", but insist on at least the 3rd edition, where Barbara Moo joined the team!)
sbi
I read Lippmann's "C++ Primer" when it first came out (a long time ago now) and thought it went on and on about the most obvious things - I haven't read any but the first ed though. And perhaps I'm not the ideal test bed for C++ tutorials...
anon
I just ordered Accelerated C++. Amazon.com thanks you.
scribbles