Thread: help with class structure assignment

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    17

    Question help with class structure assignment

    I'm doing an assignment where you have to create class structures. The problem I'm having is when you read in a string into the array. Here is my program so far:

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    const int NUMCONS = 15;
    class author_name {
          public:
                 string last;
                 string first;
    };
    class other_info {
          public:
                 string publisher;
                 int year;
    };
    
    class book_info {
          public:
                 
                 string title; 
                 int pages;
                 string genre;
                 other_info other;
    };
    
    class mybooks {
          public:
                 author_name name;
                 book_info book;
    };
    void readdata (mybooks [], int &);
    void prettyprint (mybooks [], int);
    int main () 
    {
        mybooks library[NUMCONS];
        int num;
        
    
           readdata (library, num);
           prettyprint (library, num);
        
        
        
        return 0;
    }
    void readdata (mybooks library [], int &num)
    {
         ifstream cfile("program8in.dat");
         cfile >> num;
            
         
         for (int count = 0; count < num; count++) {
             cfile >> library[count].name.last;
             cfile >> library[count].name.first;
             cfile >> library[count].book.title;
             cfile >> library[count].book.pages;
             cfile >> library[count].book.genre;
             cfile >> library[count].book.other.publisher;
             cfile >> library[count].book.other.year;
             
         
         }
         cfile.close();
         return;
    }
    void prettyprint (mybooks library [], int num)
    {    
         ofstream dbfile("program8.out");
         
         for (int count= 0; count < num; count++) {
             dbfile << "\t" << library[count].name.last;
             dbfile << "\t" << library[count].name.first;
             dbfile <<"\t" << library[count].book.title;
             dbfile <<"\t" << library[count].book.pages;
             dbfile <<"\t" << library[count].book.genre;
             dbfile <<"\t" << library[count].book.other.publisher;
             dbfile <<"\t" << library[count].book.other.year;
             dbfile << endl;
         } 
         
         dbfile.close();
         return;
    }
    Here is my data file:

    Code:
    2
    Jk Rowling
    Harry  167 Fantasy Scholastic 1999
    JRR Tolkien
    LOTR 999 Fantasy Penguin 1956
    And this is my output:
    Jk
    Code:
    	Rowling	Harry	167	Fantasy	Scholastic	1999
    	JRR	Tolkien	LOTR	999	Fantasy	Penguin	1956
    But let's say I want the title to be "Harry Potter". The program will read in "Harry" into a different location in the array from "Potter".

    I've tried using getline(), because that's the only thing I can think of to do that.

    I tried this:

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    const int NUMCONS = 15;
    class author_name {
          public:
                 string last;
                 string first;
    };
    class other_info {
          public:
                 string publisher;
                 int year;
    };
    
    class book_info {
          public:
                 
                 string title; 
                 int pages;
                 string genre;
                 other_info other;
    };
    
    class mybooks {
          public:
                 author_name name;
                 book_info book;
    };
    void readdata (mybooks [], int &);
    void prettyprint (mybooks [], int);
    int main () 
    {
        mybooks library[NUMCONS];
        int num;
        
    
           readdata (library, num);
           prettyprint (library, num);
        
        
        
        return 0;
    }
    void readdata (mybooks library [], int &num)
    {
         ifstream cfile("program8in.dat");
         cfile >> num;
            
         
         for (int count = 0; count < num; count++) {
             cfile >> library[count].name.last;
             cfile >> library[count].name.first;
             getline(cfile, library[count].book.title);
             cfile >> library[count].book.pages;
             getline(cfile, library[count].book.genre);
             getline(cfile, library[count].book.other.publisher);
             cfile >> library[count].book.other.year;
             
         
         }
         cfile.close();
         return;
    }
    void prettyprint (mybooks library [], int num)
    {    
         ofstream dbfile("program8.out");
         
         for (int count= 0; count < num; count++) {
             dbfile << "\t" << library[count].name.last;
             dbfile << "\t" << library[count].name.first;
             dbfile <<"\t" << library[count].book.title;
             dbfile <<"\t" << library[count].book.pages;
             dbfile <<"\t" << library[count].book.genre;
             dbfile <<"\t" << library[count].book.other.publisher;
             dbfile <<"\t" << library[count].book.other.year;
             dbfile << endl;
         } 
         
         dbfile.close();
         return;
    }
    With this data file:

    Code:
    2
    Jk Rowling
    Harry Potter  
    167 
    Science Fiction/Fantasy 
    Scholastic 
    1999
    JRR Tolkien
    Lord of the Rings 
    999 
    Science Fiction
    Penguin Classics 
    1956
    But it gives me crazy output, like this:
    Code:
    	Jk	Rowling		211400			211400
    				205920			205936
    So if someone can explain what I'm doing wrong, I'd be quite grateful.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Take a look at this code:
    Code:
         for (int count = 0; count < num; count++) {
             cfile >> library[count].name.last;
             cfile >> library[count].name.first;
             getline(cfile, library[count].book.title);
             cfile >> library[count].book.pages;
             getline(cfile, library[count].book.genre);
             getline(cfile, library[count].book.other.publisher);
             cfile >> library[count].book.other.year;
         }
    After you cin>> name.first and name.last, you will have read "Jk" and "Rowling", respectively, but you've left the newline in the stream. The call to getline will receive an empty line, and when you try to convert that empty string to a number, you get something completely random like 211400.

    So, you have to get rid of the newline. Perhaps the easiest way to do this would be to use getline() to get the line "Jk Rowlings" into one string, and then use stringstreams to parse the two parts of that line.

    Stringstreams are covered in this FAQ. In the FAQ, numbers are being extracted from the string, but it's the same idea for strings. http://faq.cprogramming.com/cgi-bin/...&id=1043284385
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    17
    Is there another way to get rid of the newline character, like cin.ignore or something like that?

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Crcullen3916 View Post
    Is there another way to get rid of the newline character, like cin.ignore or something like that?
    There's more than one way to do pretty much anything, but I'd recommend learning to use stringstreams. Really, it's not hard, and they are terribly useful things.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You could use ignore() if you wanted to, just like when you stop the console from closing:
    Code:
    in.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
    From http://faq.cprogramming.com/cgi-bin/...&id=1043284385

    But using stringstreams would be a good idea, in case you want to expand your program in the future or something.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. class structure question
    By R.Stiltskin in forum C++ Programming
    Replies: 12
    Last Post: 03-20-2008, 05:02 PM
  2. Class assignment
    By tmnismo91 in forum C Programming
    Replies: 18
    Last Post: 06-19-2007, 07:00 PM
  3. Replies: 1
    Last Post: 10-27-2006, 01:21 PM
  4. Replies: 8
    Last Post: 10-02-2005, 12:27 AM
  5. class structure
    By collegegal in forum C++ Programming
    Replies: 2
    Last Post: 03-02-2002, 04:13 PM