Solved

Read in Files.  Need some help..

Posted on 2003-11-23
13
334 Views
Last Modified: 2010-04-01
This is a homework assignment so not looking for code to be given... I need to read in a file into an array of the voter class. Here is my code below it works tested it.  Just does not look right for some reason. Another question i use getline to read in whitespace if i want to write this to data file whats the best way to do.  What makes this class harder is that the teacher usually teachers us for 40 mins when its a 2 hr class...  Here is code:

#include "fileutil.cpp"

#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
#include<string.h>
#include<ctype.h>
#include<fstream.h>

#if !defined(microsoft)
#include<stdlib.h>
#define cls() system("cls");
#endif

class Voter
{
      private:
            int idnumber;
            char lastname[25];
            char firstname[25];
            char party[2];
            int birthyear;
            int currentage;

      public:
            Voter();
            Voter(int,char[], char[], char[], int, int);
            Voter(const Voter&);
            void Read(Voter voterlist[],ifstream&, int);
            void print();
            ~Voter();
};

//*****************************************************************************
// Default Constructor                                                        *
//*****************************************************************************

Voter::Voter()
{
      idnumber = 0;
      lastname[0] = '\0';
      firstname[0] = '\0';
      party[2] = '\0';
      birthyear = 0;
      currentage = 0;
}

//*****************************************************************************
// Constructor Arguments                                                      *
//*****************************************************************************

Voter::Voter(int id,char ln[], char fn[], char pid[], int year, int by)
{
      idnumber = id;
      strcpy(lastname, ln);
      strcpy(firstname, fn);
      strcpy(party, pid);
      birthyear = year;
      currentage = 2003 - birthyear;
}

//*****************************************************************************
// Copy Constructor                                                           *
//*****************************************************************************

Voter::Voter(const Voter& v1)
{
      idnumber = v1.idnumber;
      strcpy(lastname, v1.lastname);
      strcpy(firstname, v1.firstname);
      strcpy(party, v1.party);
      birthyear = v1.birthyear;
      currentage = 2003 - v1.birthyear;
}


//*****************************************************************************
// ReadInData                                                                 *
//*****************************************************************************

void Voter::Read(Voter voterlist[], ifstream& infile, int arraysize)
{
      int  age,
             idnumber,
             birthyear,
             currentage = 0,
             numVoters  = 0;

      char lastname[25],
             firstname[25],
             party[2],
             trash[2];

      OpenInput( infile, "Give name of Data File:  " );

      while (infile.good() )
      {
            for ( int x = 0; x < arraysize; x++)
            {
            infile >> idnumber;
            infile.getline(trash,2);
            infile.getline(lastname,25,'\t');
            infile.getline(firstname, 25, '\t');
            infile.getline(party, 2, '\t');
            infile >> birthyear;
            age = 2003 - birthyear;

            voterlist[numVoters] = Voter(idnumber,lastname, firstname, party, birthyear, currentage);
            ++ numVoters;

            }

            if (infile.fail() )
                  break;
      }
      infile.close();

}


//*****************************************************************************
// Destructor                                                               *
//*****************************************************************************

Voter::~Voter()
{

}



void PrintList(Voter voterlist[], int);

void main()
{


const int arraysize = 8;
Voter voterlist[arraysize];

      ifstream infile;
      ofstream outfile;


}





void save(Voter voterlist

0
Comment
Question by:rbran1974
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
13 Comments
 

Expert Comment

by:Drew_Benton
ID: 9808403
""This is a homework assignment so not looking for code to be given... I need to read in a file into an array of the voter class. Here is my code below it works tested it.  Just does not look right for some reason. Another question i use getline to read in whitespace if i want to write this to data file whats the best way to do.  What makes this class harder is that the teacher usually teachers us for 40 mins when its a 2 hr class...  Here is code""

1. What specifically does not look right?
2. I dont fully understand your 2nd question either...plz explain fully
3. Theres always mention of a homework help policy lol
0
 

Author Comment

by:rbran1974
ID: 9808460
ok where i read in the array is there a better way of doing this.
0
 
LVL 4

Accepted Solution

by:
n_fortynine earned 53 total points
ID: 9809025
>>   while (infile.good() )
>>     {
 >>         for ( int x = 0; x < arraysize; x++)
 >>         {
 >>         infile >> idnumber;
>>          infile.getline(trash,2);
>>          infile.getline(lastname,25,'\t');
>>          infile.getline(firstname, 25, '\t');
>>          infile.getline(party, 2, '\t');
>>          infile >> birthyear;
>>          age = 2003 - birthyear;
>>
>>          voterlist[numVoters] = Voter(idnumber,lastname, firstname, party, birthyear, currentage);
>>          ++ numVoters;
>>
>>          }
>>
>>          if (infile.fail() )
>>               break;
>>     }

How about:
   while (numVoters < arraysize && infile >> idnumber)
   {
          infile.getline(trash,2);
          infile.getline(lastname,25,'\t');
          infile.getline(firstname, 25, '\t');
          infile.getline(party, 2, '\t');
          infile >> birthyear;
          age = 2003 - birthyear;

          voterlist[numVoters] = Voter(idnumber,lastname, firstname, party, birthyear, currentage);
          ++ numVoters;
    }
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 17

Assisted Solution

by:rstaveley
rstaveley earned 52 total points
ID: 9810846
An alternative to using getline with '\t' is to use a std::setw manipulator to set the maximum field width.

e.g.
        char firstname[24+1];
        infile >> std::setw(sizeof(firstname)) >> firstname;

However, the disadvantage with adopting this approach is that you can't have names with spaces in.

If you do go the manipulator route, with Josuttis's ignoreLine manipulator, you can do...

        infile >>  ignoreLine

...to eat up any remaining junk to the end of a line. The manipulator is defined as a template at http://www.josuttis.com/libbook/io/ignore.hpp.html . I like it.

This approach and your approach both need some additional handling in the event that you have an input field which is too large (e.g. a > 24 character name). In both cases, it will run into the next field.

Since all of your fields are delimited by '\t', I'd be inclined to tokenise the input line into std::strings:
--------8<--------
#include <iostream>
#include <vector>
#include <string>

int main()
{
      std::string str;
      while (getline(std::cin,str)) {
            std::vector<std::string> token;
            std::string::size_type pos1 = 0,pos2;
            while ((pos2 = str.find('\t',pos1)) != std::string::npos) {
                  token.push_back(str.substr(pos1,pos2-pos1));
                  pos1 = pos2+1;
            }
            /*if (!str.substr(pos1).empty())*/                                
                  token.push_back(str.substr(pos1));
            for (int i = 0;i < token.size();i++)
                  std::cout << "Token " << i+1 << ": " << token[i] << '\n';
      }
}
--------8<--------
You can then use the strings separately.

e.g.
      const int LastName = 0;        
      const int FirstName = 1;
      std::string lastName = token[LastName].substr(0,24);
      //...

I notice you are using deprecated headers (ones with .h), which may mean that you've got an old compiler, which predates support for namespaces. If so, you'll need to lose the std:: prefixes in this to get it to work on your compiler.
0
 
LVL 3

Expert Comment

by:RJSoft
ID: 9811589
One thing about getline it does not stop until it gets the newline char. So putting a largish value like 100 or even 200 helps, otherwise you can get a messed up string if someone enters a large string.

RJ
0
 
LVL 2

Expert Comment

by:federal102
ID: 9812502
I hope that you are just starting out in this class and that your teacher will demonstrate some knowledge of C++ rather than teaching C with classes. C++ has alot of functionality that would help with this code. Please do not take this a a put down on your code, but rather a commentary on the way that C++ is often taught. I experienced the same problemsa as you with an frequently absentee lecturer - luckily the TA's were excellent.

That being said I have updated your code a little to demonstrate some C++ tricks..

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

using namespace std; // used for brevity (actually bad form)



class Voter
{
     private:

          int idnumber;
          string lastname;  //use std::string vs C string - no need to worry about string length now
          string firstname;
          string party;
          int birthyear;
          int currentage;

     public:
          Voter();
          Voter(int,string &, string &, string &, int, int);
          Voter(const Voter&);
              //The Read function does not belong in the Voter class (IMHO)
          //void Read(Voter voterlist[],ifstream&, int);
          void print();
          ~Voter();
          friend ostream & operator << (ostream &o, Voter &v); // use to write to file
};

//*****************************************************************************
// Default Constructor                                                        *
//*****************************************************************************

Voter::Voter() //initialize instance via M.I.L. (member initialization list)
:idnumber(0),
 lastname(" "),
 firstname(" "),
 party(" "),
 birthyear(0),
 currentage(0){}


//*****************************************************************************
// Constructor Arguments                                                      *
//*****************************************************************************

Voter::Voter(int id, string &ln, string &fn, string &pid, int year, int by) // use M.I.L.
:idnumber(id),
 lastname(ln),
 firstname(fn),
 party(pid),
 birthyear(year)
{
     currentage = 2003 - birthyear;
}

//*****************************************************************************
// Copy Constructor                                                           *
//*****************************************************************************

Voter::Voter(const Voter& v1)
{
     idnumber = v1.idnumber; // can now use op =  vs C strcpy function
     lastname = v1.lastname;
     firstname = v1.firstname;
     party = v1.party;
     birthyear = v1.birthyear;
     currentage = 2003 - v1.birthyear;
}


//*****************************************************************************
// ReadInData                                                                 *
//*****************************************************************************

/*void Voter::Read(Voter voterlist[], ifstream& infile, int arraysize)
{
     int  age,
           idnumber,
           birthyear,
           currentage = 0,
           numVoters  = 0;

     char lastname[25],
           firstname[25],
           party[2],
           trash[2];

     OpenInput( infile, "Give name of Data File:  " );

     while (infile.good() )
     {
          for ( int x = 0; x < arraysize; x++)
          {
          infile >> idnumber;
          infile.getline(trash,2);
          infile.getline(lastname,25,'\t');
          infile.getline(firstname, 25, '\t');
          infile.getline(party, 2, '\t');
          infile >> birthyear;
          age = 2003 - birthyear;

          voterlist[numVoters] = Voter(idnumber,lastname, firstname, party, birthyear, currentage);
          ++ numVoters;

          }

          if (infile.fail() )
               break;
     }
     infile.close();

}*/


//*****************************************************************************
// Destructor                                                               *
//*****************************************************************************

Voter::~Voter()
{

}

void PrintList(Voter voterlist[], int);

ostream & operator << (ostream &o, Voter &v)
{
      return o << v.idnumber << "\t"
                   << v.lastname << "\t"
                   << v.firstname << "\t"
                   << v.party << "\t"
                   << v.birthyear;
}


int main() // main should always rturn int not void
{
  vector<Voter> voterlist; //use vector vs array (no need to know how many records are on file)
  string filename, trash, lastname, firstname, party, idnumber, birthyear, temp;
  int age = 0;

  cout << "Enter file name: ";
  cin >> filename;
  ifstream infile(filename.c_str());
  istream fin(infile);
  if(!infile)
  {
        cout << "File not found" << endl;
      return 0;
  }
  while(!fin.eof())
  {
      getline(fin, temp);
      istringstream ss(temp); // use istringstream to parse the file
      ss >> idnumber >> lastname >> firstname >> party >> birthyear;
      age = 2003 - atoi(birthyear.c_str()); // convert string to int (it's a C function - sometimes they're useful
      voterlist.push_back(Voter(atoi(idnumber.c_str()), lastname, firstname, party, atoi(birthyear.c_str()), age));
  }
      string outputfile;
      cout << "Enter name for output file: ";
      cin >> outputfile;

    ofstream outfile(outputfile.c_str());
      vector<Voter>::iterator i = voterlist.begin();
      while (i != voterlist.end())
      {
            outfile << *i << endl; //outputs records to file.
            ++i;
      }
      return 0;
}
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9812553
>  ss >> idnumber >> lastname >> firstname >> party >> birthyear;
>  age = 2003 - atoi(birthyear.c_str()); // convert string to int (it's a C function - sometimes they're useful

Or indeed go all the way and have birthyear as an int. Nice to lose the C :-)
0
 

Author Comment

by:rbran1974
ID: 9815484
Thanks for all the help so far.. I saw my teacher for the first time in almost 2 weeks.  Asked her if I could use vector for this project and she told me no.  So here is the question.  I need to be able to add another voter to the database.  How would i go about changing the array size if its defined as a constant. I cannot use a vector ( would make this easier).  

Also I cleaned up my code alittle.


#include "fileutil.cpp"

#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
#include<string.h>
#include<ctype.h>
#include<fstream.h>

#if !defined(microsoft)
#include<stdlib.h>
#define cls() system("cls");
#endif

class voter
{

private:      
      int  idnumber;
      char lastname [25];
      char firstname[25];
      char party         [2];
      int  birthyear;
      int  currentage;

public:
      voter();
      voter(int,char[], char[], char[], int, int);
      voter(const voter&);
      void operator = (const voter&);
      void print();
      void disksave(ofstream& outfile);
      ~voter();

};


// =========================== Default Constructor =================================

voter::voter()
{
      idnumber       =   0;
      lastname [0]   = '\0';
      firstname[0]   = '\0';
      party    [0]   = '\0';
      birthyear      =   0;
      currentage     =   0;
}


// =========================== Constructor with Arguments ==========================

voter::voter(int id,char ln[], char fn[], char pid[], int year, int by)
{
      idnumber   = id;
      strcpy(lastname, ln);
      strcpy(firstname, fn);
      strcpy(party, pid);
      birthyear  = year;
      currentage = 2003 - birthyear;
}


// =========================== Copy Constructor ====================================


voter::voter(const voter& v1)
{
      idnumber   = v1.idnumber;
      strcpy(lastname, v1.lastname);
      strcpy(firstname, v1.firstname);
      strcpy(party, v1.party);
      birthyear  = v1.birthyear;
      currentage = 2003 - v1.birthyear;
}


// =========================== Assignment Operator  ================================

void voter::operator = (const voter& v1)
{
      idnumber   = v1.idnumber;
      strcpy(lastname, v1.lastname);
      strcpy(firstname, v1.firstname);
      strcpy(party, v1.party);
      birthyear  = v1.birthyear;
      currentage = 2003 - v1.birthyear;
}


// =========================== Display List of Voters  =============================

void voter::print()
{
      cout << idnumber    << setw(12)
              << lastname    << setw(12)
             << firstname   << setw(12)
           << party       << setw(12)
             << birthyear      << setw(12)
             << currentage  << setw(12)
         << endl;
}


// =========================== Save to File on Disk ================================

void voter::disksave(ofstream& outfile)
{
outfile  << idnumber    << setw(12)
              << lastname    << setw(12)
             << firstname   << setw(12)
           << party       << setw(12)
             << birthyear      << setw(12)
             << currentage  << setw(12)
         << endl;
}


// =========================== Destructor Argument  ================================

voter::~voter()
{

}



void getdata( voter voterlist[], int&, ifstream&);
void savefile(voter voterlist[], int , ofstream&);
void printreport( voter voterlist[], int);


void main()
{

      const int arraysize = 8;
              int error     = 0;
             
      voter voterlist[arraysize];
      
      ifstream infile;
      ofstream outfile;

      getdata (voterlist, error, infile);
      savefile(voterlist, error, outfile);
      
      //printreport(voterlist, error);



}


void getdata( voter voterlist[], int& error, ifstream& infile)
{
      int            age,
                  idnumber,
                  birthyear,
                  currentage  = 0,
                  numvoters   = 0;

      char    lastname[25],
                firstname[25],
                party[2],
                trash[2];

OpenInput( infile, "Give name of Data File:  " );

while (infile.good() )
{
      infile >> idnumber;
      infile.getline(trash,2);
      infile.getline(lastname,25,'\t');
      infile.getline(firstname, 25, '\t');
      infile.getline(party, 2, '\t');
      infile >> birthyear;
      age = 2003 - birthyear;

 if ((strcmp(party, "r") == 0) || (strcmp(party, "R") == 0)  ||
      ( strcmp(party, "d") == 0) || (strcmp(party, "D") == 0)  ||
      ( strcmp(party, "l") == 0) || (strcmp(party, "L") == 0)  ||
      ( strcmp(party, "c") == 0) || (strcmp(party, "C") == 0))
 {
      if ((idnumber > 1000) && ( idnumber < 10000))
      {
            if ((age > 17) && (age < 126))
            {
            voterlist[numvoters] = voter(idnumber,lastname, firstname, party, birthyear, currentage);
            ++ numvoters;
            }
            else
            error = error + 1;
            }
            else
            error = error + 1;
            }
            else
            error = error + 1;

      if (infile.fail())
      break;
}
infile.close();
}


void printreport(voter voterlist[], int error)
{

      for (int n = 0;n<(8 - error) ;n++)
      {
            voterlist[n].print();
      }
}


void savefile(voter voterlist[], int error, ofstream& outfile)
{
      OpenOutput(outfile);

      for (int n = 0;n<(8 - error) ;n++)
      {
            voterlist[n].disksave(outfile);
      }
}



0
 

Author Comment

by:rbran1974
ID: 9815504
another thing. when i read in the file if one of the elements in the feild dont meet the requirements i increment error by 1.  Then when i go to print the array i do  

for (int n = 0;n<(8 - error) ;n++)
     {
          voterlist[n].print();
     }

it works, but is there better way.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9816298
Presumably, your teacher wants you not to use the standard library's std::string too.

If you need an array size to be determined at run run, you can use the new and delete[] operators.

e.g. For a name member of your class:

class X {
char *name;
public:
    X(const char *name)
    {
        X::name = new char[strlen(name)+1];
        strcpy(X::name,name);
    }
    ~X()
    {
        delete []name;
    }
};

If you've not yet covered new and delete in your course, you should simply make your arrays big enough for the worst case.

The voter array could be dynamically allocated to be an appropriate right size at run time using new and []delete, or - if you've reached that point in your course - you could construct a "linked list" of voters. However, if your teacher has yet to introduce you to the standard library's vector<>, I assume that you won't be able to use the standard library's list<>, which presumable means you'd need to implement your own lined list, which is something that C programmers dirty their hands with.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9816303
> when i read in the file if one of the elements in the feild dont meet the requirements i increment error by 1

It would be more normal to have a flag in the class to indicate that whichever field was corrupt. Alternatively, don't load the array with that class.
0
 
LVL 9

Expert Comment

by:tinchos
ID: 10285754
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Split: n_fortynine {http:#9809025} & rstaveley {http:#9816303}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
No module found pypyodbc, 3 58
How do I get Window Title of all opened process? 4 61
what type of pointer is this pointer? 3 31
Bitwise and to sum elements 2 53
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question