Thread: Saving a file

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    12

    Saving a file

    I'm making a program that can write RSS files. Now so far everything works right, except one thing, whenever I create a new RSS file (it can open or create a new one), it either doesn't save the file until it exits, which is bad because I need to read the file afterwards. This is my code:

    Code:
    //Headers
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    //Channel info
    struct channel {
           string title;
           string desc;
           string link;
           };
    
    //Item info
    struct item {
           string title;
           string desc;
           string link;
           string size;
           string type;
           int pos;
           };
           
    //Set up Cahnnel and Items
    channel chan;
    item items[100];
    
    //Other variables
    bool inItem = false;
    bool inChan = false;
    bool inRSS = false;
    string fileName;
    char fileNameChar[100]; //Because fileName can't be string when used with i/o fstream
    bool newFile = false;
    string file[500]; //Will store the file by lines for easier accessing/editing
    int numLines;
    string line; //Used to store individual lines when needed
    
    // Function Prototypes
    void insertLine(int pos, string lineInserted);
    
    //Start of program
    int main() {
        cout << "RSS File Maker" << endl << "By: TyPR124" << endl << endl;
        cout << "What is the name of the RSS file? (NOTE: \"NEW\" will create a new file)" << endl;
        getline(cin, fileName);
        
        if (fileName == "NEW") {
                     newFile = true;
                     cout << endl << "What should your file be called?" << endl;
                     getline(cin, fileName);
        }
        
        //Check if fileName ends in .xml, add if it doesn't
        //FIRST CHECK MUST BE IF LENGTH IS < 5 B/C ERROR WILL HAPPEN IF TRY TO GET SUBSTR STARTING FROM NEGATIVE #
        if ( (fileName.length() < 5) || (fileName.substr(fileName.length()-4, fileName.length() ) != ".xml") ) {
           fileName = fileName + ".xml";
        }
        //Convert fileName to fileNameChar so it can be used with i/o fstream
        for (int a=0; a<=fileName.length(); a++) {
            fileNameChar[a] = fileName[a];
        }
        
        //Open file for reading/writing (use extend for writing)
        ifstream RSS_read (fileNameChar);
        ofstream RSS_write (fileNameChar, ios::app);
        
        RSS_read.close();
        RSS_write.close();
        
        //If file is new, write channel title, desc, and link
        if (newFile) {
                     RSS_write.open(fileNameChar, ios::app);
                     RSS_write << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl << "<rss version=\"2.0\">";
                     RSS_write.close();
                     
                     cout << endl << endl << "What is the name of the RSS Channel?" << endl;
                     getline(cin, chan.title);
                     
                     RSS_write.open(fileNameChar, ios::app);
                     RSS_write << endl << endl << "<channel>" << endl << endl;
                     RSS_write << "<title>" << chan.title << "</title>" << endl;
                     RSS_write.close();
                     
                     cout << endl << "What is the description of the RSS Channel?" << endl;
                     getline(cin, chan.desc);
                     
                     RSS_write.open(fileNameChar, ios::app);
                     RSS_write << "<description>" << chan.desc << "</description>" << endl;
                     RSS_write.close();
                     
                     cout << endl << "What is the link to the RSS Channel?" << endl << "NOTE: IT MUST BE A FULL HTTP LINK" << endl;
                     getline(cin, chan.link);
                     
                     RSS_write.open(fileNameChar, ios::app);
                     RSS_write << "<link>" << chan.link << "</link>" << endl;
                     RSS_write.close();
        }
        
        //Save the RSS File in the var. file and find the number of lines
        RSS_read.open(fileNameChar);
        for (int a=0; getline(RSS_read, line); a++) {
            file[a] = line;
            numLines = a; //I won't count the first line as a numbered line because it MUST ALWAYS be the same in RSS files
        }
        
        //Check the first line to make sure it is valid
        if (file[0].substr(0, 18) == "<?xml version=\"1.0\"") {
           file[0] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
        }
        else {
            insertLine(0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        }
        
        
        //TEST
        for (int a=0; a<=numLines+1; a++) {
            cout << file[a] << endl;
        }
        cin.ignore();
        cin.get();
    }
    
    
    void insertLine(int pos, string lineInserted) {
         string temp[500];
         for (int a=0; a<500; a++) {
             temp[a] = file[a];
         }
         file[pos] = lineInserted;
         
         for (int a = pos+1; a <= numLines+1; a++) {
             file[a] = temp[a-1];
         }
    }
    The problem seems like it's not saving the file directly after I close it, because if I take out the check of the first line, it couts nothing, but if I leave it in it only couts the first line. And when I open the file it's the way it's supposed to be. So is there a way I can manually save the file? Thanks.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Don't use global variables.
    You can use std::string.c_str() to get a C-style if you need it. I don't think istream or ostream should need a C-style string to open a file.
    You can flush a stream to force the output to be written. Dunno how you do it with ostream, though.

  3. #3
    Registered User
    Join Date
    Nov 2007
    Posts
    12
    Whats wrong with global variables? Besides, I would have to use some of them global unless want to constantly pass variables back and forth through functions.

    And flush-ing it didn't work. Also, as far as I know, endl is supposed to do the same thing as flush and add a line at the same time anyway... I tried manually changing the numLines before couting to see if that had to do with it, but that just gave me a bunch of blank lines. So now I can't think of anything else that could possibly be wrong with it other than not saving the file right away.

    EDIT: I could make a work-around by putting the info for the new file in the array, but then I'm not sure if I'll need to read the file itself later... but if no one can come up with something, I guess thats what I'll have to do.
    Last edited by TyPR124; 11-30-2007 at 04:36 PM.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by TyPR124 View Post
    Whats wrong with global variables? Besides, I would have to use some of them global unless want to constantly pass variables back and forth through functions.
    Then pass them back and forth. Avoid global variables at all costs. Anyone here will tell you the same thing.
    Why is this? Because all and every function can modify these, whileas if you pass them as arguments, only the function that gets them can modify them. Common sense. You can also do const on arguments you pass so the functions won't modify them. You can't do that on global variables if you want to modify them.
    So avoid them!

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    And flush-ing it didn't work. Also, as far as I know, endl is supposed to do the same thing as flush and add a line at the same time anyway...
    Yes, that's right, for buffered streams. http://www.cplusplus.com/reference/i...tors/endl.html
    cout and any files should all be buffered unless you specify otherwise.

    I don't think istream or ostream should need a C-style string to open a file.
    They do.
    Code:
    std::ifstream compiler_error(std::string("file.txt"));
    std::ifstream perfectly_acceptable("file.txt");
    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.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    That seems weird to me. Considering the framework is built to accept std::string. Meh, you can still call c_str() anyway.

  7. #7
    Registered User
    Join Date
    Nov 2007
    Posts
    12
    Yeah, I was surprised to find it didn't accept strings, but still an easy fix... Now if only my problem was as easy of a fix (well it probably is, I'm just probably doing something really stupid). I guess I'll put it in the info for the new file in the file variable and continue from there. Hopefully I don't ever need to read the file after that though.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    As Elysia said: the designers of std::string did consider that you may want to use it for "old C style string stuff", so if you have a std::string a, you can get a C "char array" string by calling s.c_str(), you don't need to convert it yourself.

    --
    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.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by matsp View Post
    std::string a ... s.c_str()


    a or s, not both

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Not having a particularly good day today, that's the second typo in about two minutes... Yes, it should be a.c_str() of course.

    --
    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.

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    As Elysia said: the designers of std::string did consider that you may want to use it for "old C style string stuff", so if you have a std::string a, you can get a C "char array" string by calling s.c_str(), you don't need to convert it yourself.
    Note that you can't necessary do everything you'd like with std::string::c_str(), because it returns a const string. You can easily make a copy of the string for your own purposes, of course.
    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. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  2. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM