Solved

ofstream headache!!

Posted on 2004-04-23
4
1,129 Views
Last Modified: 2012-08-14
ok, I admit I haven't touched C for a while, so it could be a really obvious mistake. But im starting to write a simple html builder that reads in a script file (.txt format), looks for tags and outputs html pages.

So far, It reads in the script, parses it and produces a html page, when it loops back round to make the 2nd file, this is where it doesnt work, and its drivin me mad!

Source code
--------------

#include <iostream>
#include <istream>
#include <fstream>
#include <string>
using namespace std;

// the below will need to be changed, open an output file for each script
// just ask for a path

int main()
{
      
      ////////////////////////////////////////////////////////////////////////////////////////
      // do some kinda menu eventually, allow user to fine tune global variables, directories etc
      ////////////////////////////////////////////////////////////////////////////////////////
      /*
      int quit=0;
      
        while (quit!=1)
        {
        // do the menu here
        
            }
            
      */
      
      
      ////////////////////////////////////////////////////////////////////////////////////////
      // declare an output file, will be dynamic eventually!
      ofstream myFile("c:\\out.html");

      if (! myFile)
      {
            // if it buggers up, exit
            cout<< "Error Setting file" << endl << endl;
            return -1;
      }
      
      char buffer[4096];
      int nbuf=1024; // buffer
      
      string inputFile;
      
      // do some kinda menu thing
      cout << "Please give the path of the script file (must be txt file)" << endl << endl;
      cout << "-:";
      cin >> inputFile;
      cout << endl << endl;
      
      ifstream readFile;
      readFile.open(inputFile.c_str());
      if (!readFile.is_open())
      {
            cout << "Error Opening File, try again" << endl << endl;
      }
      //readFile.getline (buffer,100);
      //string test;
      
      /*
      This is the logic code for the main program loop....
      take the entire script.txt file. See the additional code format file
      to see what special characters need to be included.
      
        open file..
        
            read first line
            go through each character to check for trigger codes.
            if code = <course> set course name
            if code = <modulename> set modulename to this
            if code = <submodule> name set submodule name to this
            if code = <page> set page num to this, or add one on to last page counter
            after this all the content goes in,
            
              finally loop until a <closepage> tag is found, then close file,
              and go back to main loop. This will work because everything between
              the <page> and <closepage> tags will be page content :)
              works in theory!!!!
             
      */
      string temp;
      
      // read a line in from the source file.
      readFile.getline (buffer,nbuf);
      // output it (debug only)
      cout << buffer << endl;
      // check buffer to see if it contains a trigger element
      // some debug code
      temp=buffer;

      ////////////////////////////////////////
      // variables
      ////////////////////////////////////////
      string coursename, modulename, submodulename;
      // depends on how the page attribute will be used
      string strpage;
//      int numpagetags, closepagetags;
      int noclose=0;
      int pagenumber=0;
      string outputpath;
      
      unsigned int loc = temp.find( "<course>", 0 );
      if( loc != string::npos )
      {
            cout << "Course name found!" << endl;
            noclose=1;
            
            // found course, therefore file is ok...
            // now do a loop to go thru the entire file
            while (!readFile.eof())
            {
                  // start readin in file
                  readFile.getline (buffer,nbuf);
                  cout << buffer << endl;
                  temp=buffer;
                  myFile << "TEST";
                  myFile << temp.capacity();
                  cout << "From the buffer: " << temp << endl;
                  //myFile << "This is a new line";
                  ////////////////////////////////////////////
                  // do element checking first
                  ////////////////////////////////////////////
                  // if a main module
                  loc = temp.find( "<modulename>", 0 );
                  if( loc != string::npos )
                  {
                        // is a mainmodule
                        cout << "Module name found!" << endl;
                        // now parse the name from the string
                        // and set to variable
                        // Set module name, erase first 12 chars from string
                        temp.erase(0, 12);
                        modulename=temp;
                        noclose=1;
                  }
                  // if a sub module
                  loc = temp.find( "<submodule>", 0 );
                  if( loc != string::npos )
                  {
                        // is a mainmodule
                        cout << "Sub Module name found!" << endl;
                        // now parse the name from the string
                        // and set to variable
                        // erase first 11 chars
                        temp.erase(0,11);
                        submodulename=temp;
                        noclose=1;
                  }
                  // look for page tag
                  loc = temp.find( "<page>", 0 );
                  if( loc != string::npos )
                  {
                        // is a mainmodule
                        cout << "Page found!" << endl;
                        //numpagetags=numpagetags+1;
                        // now parse the name from the string
                        // and set to variable
                        //////////////////////////////////
                        // When a new page is encountered, set
                        // to new location
                        // will need variables to keep track
                        // now create a page
                        
                        // the file is now open can can be output to
                        // generic header information. Used when <page> is called
                        myFile << temp;
                        cout << "Should be outputting file info" << endl;
                        cout << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">" << endl;
                        myFile << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">";
                        myFile << endl;
                        myFile << "<HTML lang=\"en\">";
                        myFile << endl;
                        myFile << "<HEAD>";
                        myFile << endl;
                        myFile << "<TITLE>" << modulename << "</TITLE>";
                        myFile << endl;
                        myFile << "<LINK rel=\"stylesheet\" href=\"../../../includes/custom.css\" type=\"text/css\">";
                        myFile << endl;
                        myFile << "</head>";
                        myFile << endl;
                        myFile << "<body>";
                        myFile << endl;
                        myFile << "<h2>" << submodulename << "</h2>";
                        myFile << endl;
                        ///////////////////////////////////////////////////////////
                        noclose=1;
                  }
                  loc = temp.find( "<closepage>", 0 );

                  if( loc != string::npos )
                  {
                        // output content
                        ///////////////////////////////////////////////////////////
                        // end of generic html content
                        myFile << "</body>";
                        myFile << endl;
                        myFile << "</html>";
                        noclose=1;
                        // add one to page num and change output file
                        pagenumber=pagenumber+1;
                        outputpath="c:\\out" && pagenumber && ".html";
                        // close old file, and reopen under different name
                        myFile.close();
                        myFile.open("c:\\out2.html");
                        // line below works...
                        myFile << "FFS, WORK!" << endl;
                        noclose=0;
                  }
                  
                  
                  /////////////////////////////////////////////
                  // End of element search
                  /////////////////////////////////////////////

                  /////////////////////////////////////////////
                  /////////////////////////////////////////////
                  /************CONTENT************************/
                  // else is page content
                  if (noclose==0)
                  {
                        //cout << temp.length() << endl;
                        // all the work on the content will go in this if statement....
                        
                        //      cout << temp << endl;
                              // at the mo using a closed p tag
                              myFile << "<p>" << temp  << "</p>";
                  }
                  /**************END OF CONTENT **************/
                  /////////////////////////////////////////////
                  /////////////////////////////////////////////
                  noclose=0; // reset
            
                  
                  
            }
      }
      else
      {
            cout << "Didn't find Course, invalid file!" << endl;
            // therefore quit
            
            return -1;
      }
      
      
      // close files
      myFile.close();
      readFile.close();
      return 0;
}



----------------------------------------------

The script.txt file contains:

<course> This is an example script file
<modulename> tempmod name
<submodule> name of submodule
<page>
all this crap will go on the page
include a picture etc. The program will load each page and work out
the best template for it, if not it will try to create one.
(not yet implemented)
end of file!
<closepage>
<modulename> it nay work!
<page>
this is another page
2 lines

and a blank.
<closepage>


--------------------

From the code you should hopefully be able to work out my logic. If u copy the script.txt file to C:, then when you run the program type in:
c:\script.txt, it loads the file and creates 2 html files, out and out2 (on c:)

The first file is fine, but the 2nd doesnt contain what it should! i can output code to myFile but not from the input buffer of the script file. I've used various buffer sizes but has no effect. Im using ms vis studio 6. you will see i have output the stuff to the console window, and that temp and buffer are not null, and i know it performs certain If statements, but wont output certain code! AAARH!

Its a 350 pointer just cos its killing me and I need to get this sorted pronto just so I can carry on developing it.

Any help would be greatly appreciated!

James
0
Comment
Question by:jaydeeuk
[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
  • 2
4 Comments
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 10898737
What do you expect to find in out2.html?
I've compiled your program with the GNU C++ compiler, and I'm getting this output:

FFS, WORK!
<p><closepage></p>TEST20<p></p>TEST20<p></p>

0
 
LVL 4

Expert Comment

by:oumer
ID: 10899010
I stepped into your code, your problem lies in these lines

myFile << "</body>";
                    myFile << endl;
                    myFile << "</html>";
                    noclose=1;
                    // add one to page num and change output file
                    pagenumber=pagenumber+1;
                    outputpath="c:\\out" && pagenumber && ".html";
                    // close old file, and reopen under different name
                    myFile.close();
                    myFile.open("c:\\out2.html");

The first time, you started with myFile as out.html and then myFile is closed and you open it with out2.html

Now when you are working with out2.html, you close it and then you reopen it again with the same file name

That is why you dont see the expected output. If you are using some debugger, stop it just after myFile.close, and at that point out2.html looks pretty cool , but after you reopen it and write again, things get screwed
0
 
LVL 4

Accepted Solution

by:
oumer earned 350 total points
ID: 10899074
To make it clear instead of myFile.open("c:\\out2.html") use
myFile.open("c:\\out2.html", ios_base::app); //so that you append in the file opened

And I put a global variable call counter that is increamented each time you call myFile.open in the main loop

So now your code is like:


if( loc != string::npos )
               {
                    // output content
                    ///////////////////////////////////////////////////////////
                    // end of generic html content
                    myFile << "</body>";
                    myFile << endl;
                    myFile << "</html>";
                    noclose=1;
                    // add one to page num and change output file
                    pagenumber=pagenumber+1;
                    outputpath="c:\\out" && pagenumber && ".html";
                    // close old file, and reopen under different name
                    myFile.close();
                    myFile.open("c:\\out2.html",  ios_base::app);
                  myFile << "Writing " << counter++ << endl;
                  // line below works...
                    myFile << "FFS, WORK!" << endl;
                    noclose=0;
               }
               
And out2.html will look like



Writing 0
FFS, WORK!
<p><closepage></p>TEST31TEST31<page><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML lang="en">
<HEAD>
<TITLE> it nay work!</TITLE>
<LINK rel="stylesheet" href="../../../includes/custom.css" type="text/css">
</head>
<body>
<h2> name of submodule</h2>
TEST31<p>this is another page</p>TEST31<p>2 lines</p>TEST0<p></p>TEST31<p>and a blank.</p>TEST31</body>
</html>Writing 1    ----->see comment below
FFS, WORK!
<p><closepage></p>

//You see, here you started writing again, in your original program you didn't use ios_base::app for a ppending, so you loose everything before this line





0
 

Author Comment

by:jaydeeuk
ID: 10916438
Cheers, new it would be something stupid!
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

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…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

742 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