Solved

Read in Files.  Need some help..

Posted on 2003-11-23
13
322 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
13 Comments
 

Expert Comment

by:Drew_Benton
Comment Utility
""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
Comment Utility
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
Comment Utility
>>   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
 
LVL 17

Assisted Solution

by:rstaveley
rstaveley earned 52 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 17

Expert Comment

by:rstaveley
Comment Utility
>  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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
> 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
Comment Utility
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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
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.

772 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now