Thread: Reading from a vector to a file

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    36

    Reading from a vector to a file

    I am trying to write a bibliography program that puts the book's info into a vector, then writes it to a file. Can someone tell me why my "biblio" file is blank when I'm done with this program?

    Code:
    #include <string>
    #include <fstream>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <iostream>
    #include <iterator> 
    using namespace std;
    
    class BookInfo
    {
    private:
       char *author;
       char *title;
       char *publisher;
       char *isbn;
       char *date;
       
    public:
       BookInfo(){}
       ~BookInfo(){}
       vector <std::string> bookInfo;
       void printBook()
       {
          cout << "\n    Author      : " << author;
          cout << "\n    Title       : " << title;
          cout << "\n    Publisher   : " << publisher;
          cout << "\n    ISBN        : " << isbn;
          cout << "\n    Date        : " << date;
       }
       void setAuthor()
       {
          char temp[50];
          cout << "   Please enter author: ";
          cin.getline(temp, 99);
          int size = strlen(temp);
          author = new char[size];
          strncpy(author, temp, strlen(temp));
          author[size] = '\0';
          bookInfo.push_back (author);
       }  
       
       void setTitle()
       {
          char temp[50];
          cout << "   Please enter title: ";
          cin.getline(temp, 99);
          int size = strlen(temp);
          title = new char[size];
          strncpy(title, temp, strlen(temp));
          title[size] = '\0';
          bookInfo.push_back (title);
       }
       
          void setPublisher()
       {
          char temp[50];
          cout << "   Please enter publisher: ";
          cin.getline(temp, 99);
          int size = strlen(temp);
          publisher = new char[size];
          strncpy(publisher, temp, strlen(temp));
          publisher[size] = '\0';
          bookInfo.push_back (publisher);
       }
       
       void setIsbn()
       {
          char temp[6];
          cout << "   Please enter ISBN in format XXXXX: ";
          cin.getline(temp, 99);
          int size = strlen(temp);
          isbn = new char[size];
          strncpy(isbn, temp, strlen(temp));
          isbn[size] = '\0';
          bookInfo.push_back (isbn);
       }
          
       void setDate()
       {
          char temp[11];
    	  cout << "   Please enter the date in format mm/dd/yyyy: ";
          cin.getline(temp, 99);
          int size = strlen(temp);
          date = new char[size];
          strncpy(date, temp, strlen(temp));
          date[size] = '\0';
          bookInfo.push_back (date);
          write (bookInfo);
       }   
       
       void write( vector<string>& bookfile)
       {
            std::fstream biblio ("biblio.txt", std::ios_base::out);
            for (int y=0; y < bookInfo.size() ; y++ )
            {
                biblio << bookInfo[y] << ' ';
            }
       }
    };
    
    void Clear_Screen(void);
    void Flush(void);
    
    int main()
    {
       std::vector<std::string> bookInfo;
       char ans='\n';
       do
       {
       cout << "\n\nWould you like to enter book info? (Y or N): ";
       cin >> ans;
       Clear_Screen();
       cin.get();
       BookInfo book;
       book.setAuthor();
       book.setTitle();
       book.setPublisher();
       book.setIsbn();
    book.setDate();
       Clear_Screen();
       book.printBook();
       } 
       while ( ans=='y' || ans=='Y');
       cout << "\n\n   Thank you for using the program!" << endl;
       Flush();
       cout << "\n\n   Press any key to terminate . . ." << endl;
       getchar();
       return 0;
    }
    
    void Clear_Screen(void)
    {
       #ifdef _WIN32
          system("cls");
       #else
          system("clear");
       #endif
    }
    
    
    void Flush(void)
    {
       int ch;
       do
       {
          ch = getchar();
       }
       while (ch != EOF && ch != '\n');
       clearerr(stdin);
    }
    Last edited by veronicak5678; 04-09-2008 at 05:55 PM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Perhaps because every time you call the Write() function, you create a new, empty file? Try adding "|| ios::append " after "ios:ut"...

    I would also like to object to this (which is repeated several times):
    Code:
          int size = strlen(temp);
          date = new char[size];
          strncpy(date, temp, strlen(temp));
          date[size] = '\0';
          bookInfo.push_back (date);
          write (bookInfo);
    You are allocating size number of bytes, then copying a string up to strlen(temp) bytes (which is the same as size) into date, then writing to date[size] to zero, which is one byte more than the allocated bytes. (Your date array, when allocating, is from 0..size-1, so accessing date[size] is one beyond the end of the array). Finally, I fail to see the purpose of the code altogether, since all you use it for is to create a std::string, which I'm sure you could equally well do directly from the original temp string - the copying doesn't actually achieve anything other than a number of memory leaks - since the memory allocated is never freed.

    And finally, I would like to point out that:
    Code:
          char temp[11];
    	  cout << "   Please enter the date in format mm/dd/yyyy: ";
          cin.getline(temp, 99);
    is begging to overflow your buffer, since you have space for 10 chars, then ask getline to give you up to 99 chars. Use cin.getline(temp, sizeof(temp)-1) instead. Again, the same problem applies to all your input, none of which is 99/100 chars of temp string.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    36
    That part's ok. Here's what I did:



    Code:
    #include <string>
    #include <fstream>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <iostream>
    #include <iterator> 
    #include <vector>  
    
    using namespace std;
    
    class BookInfo
    {
    private:
       char *author;
       char *title;
       char *publisher;
       char *isbn;
       char *date;
       
    public:
       BookInfo(){}
       ~BookInfo(){}
       vector <std::string> bookVector;
       void printBook()
       {
          cout << "\n    Author      : " << bookVector[0];
          cout << "\n    Title       : " << bookVector[1];
          cout << "\n    Publisher   : " << bookVector[2];
          cout << "\n    ISBN        : " << bookVector[3];
          cout << "\n    Date        : " << bookVector[4];
        cout << endl;
    
    
       }
       void setAuthor()
       {
          char temp[50];
          cout << "   Please enter author: ";
          cin.getline(temp, 50);
          author = temp;
          bookVector.push_back (author);
       }  
       
       void setTitle()
       {
          char temp[50];
          cout << "   Please enter title: ";
          cin.getline(temp, 50);
          title=temp;
          bookVector.push_back (title);
       }
       
          void setPublisher()
       {
          char temp[50];
          cout << "   Please enter publisher: ";
          cin.getline(temp, 50);
          publisher = temp;
          bookVector.push_back (publisher);
       }
       
       void setIsbn()
       {
          char temp [6];
          cout << "   Please enter ISBN in format XXXXX: ";
          cin.getline(temp, 6);
          isbn = temp;
          bookVector.push_back (isbn);
       }
          
       void setDate()
       {
            char temp[11];
    	  cout << "   Please enter the date in format mm/dd/yyyy: ";
          cin.getline(temp, 11);
          date = temp;
          bookVector.push_back (date);
       }   
       
      void write()
       {
            std::fstream biblio ("biblio.txt",  std::ios_base::out|std::ios_base::app);
            for (int y=0; y < bookVector.size() ; y++ )
            {
                biblio << bookVector[y] << ' ';
            }
            biblio << "\n";
       }
    };
     
    void Clear_Screen(void);
    void Flush(void);
    
    int main()
    {
          cout << "Welcome to the Bibliography Program\n\n";
          while (true)
          {
                  char ans;
                  cout << "\nWould you like to enter book info? (Y/N)\n";
                  cin >> ans;
                  if (ans=='y' || ans =='Y')
                  {  
                      Clear_Screen();         
                      cin.get();
                      BookInfo book;
                      book.setAuthor();
                      book.setTitle();
                      book.setPublisher();
                      book.setIsbn();
                      book.setDate();
                      book.write();
                      Clear_Screen();
                      book.printBook();
                      Flush();
                  } 
                  else if (ans =='n' || ans =='N')
                  {
                       cout << "\n\n   Thank you for using the program!" << endl;
                       Flush();
                       cout << "\n\n   Press any key to terminate . . ." << endl;
                       getchar();
                       return 0;
                  }
                  else {
                       cout << "Invalid entry! Please re-try;\n";
                       ans ='y';
                  }
          }
    }
    
    void Clear_Screen(void)
    {
       #ifdef _WIN32
          system("cls");
       #else
          system("clear");
       #endif
    }
    
    void Flush(void)
    {
       int ch;
       do
       {
          ch = getchar();
       }
       while (ch != EOF && ch != '\n');
       clearerr(stdin);
    }
    Now I could use some help with the second part. I'm supposed to "Write a second program that prompts the user for partial information about a book and then supplies the rest from the bibliography file."I tried putting it into a vector and searching through that, but I can't get it to stop at the "\n". What am I doing wrong? and how can I get the info before the pointer?



    Code:
    #include <string>
    #include <fstream>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <iostream>
    #include <iterator> 
    #include <algorithm>
    
    using namespace std;
    
    
    int main()
    {
        int count;
        string identifier;
        vector<string>::iterator p;
        cout << "Enter partial info:\n";
        cin >> identifier;
        std::vector<std::string> bookVector;
        std::string line;
        std::fstream books ("biblio.txt", std::ios_base::in);
        while (books >> line)
        {
            bookVector.push_back (line);
        }
     p = find(bookVector.begin(), bookVector.end(), identifier);   
      do
      {
          cout << *p++;     
          }              
      while(*p != "\n");
      cout << endl;
      system ("pause");
    }
    Last edited by veronicak5678; 04-09-2008 at 11:02 PM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > char *author;
    This is C++, and you already include string so just use it OK.
    Your code is just riddled with char array/pointer mis-use.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    36
    OK, I changed the pointers, but that still doesn't solve my problem. Unfortunately, I don't know where the other problems are, or why they would cause that problem.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can get rid of all the char and use std::string. You can also use std::getline instead of std::cin.getline to read into a string to avoid buffer overflow issues. Then I would rethink your design. A class is meant to be an object - and if the object is a book, then it can't talk. A book would not ask for publisher information, etc. The author prints that on the book.
    In essence, that means that there shouldn't be any cin or cout inside the class. The function that creates the object must manipulate the class via member function to set specific data.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  3. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM