jaydeeuk
asked on
ofstream headache!!
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/c ustom.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
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_
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+
// 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/c
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
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Cheers, new it would be something stupid!
I've compiled your program with the GNU C++ compiler, and I'm getting this output:
FFS, WORK!
<p><closepage></p>TEST20<p