Need help with my conversion utility...

  • Thread starter Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=
  • Start date
M

Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=

Hi,

I've had a introductory C++ course in the spring and haven't programmed in
C++ for a couple of months now (but I have been programmed in C since
january). So I decided to do my conversion utility in C++, before I forget
everything. But it doesn't compile:



------------
cat export_tex.C

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


/*************************************************
* *
* This program takes data from some .vtk *
* input-files and exports them to .tex-format *
* *
*************************************************/


int main()
{
/* will contain LaTeX preamble etc */
string LaTeX_header = "test, bla.bla... \n\begin{document}\n";
string LaTeX_tail = "\end{document\n}";

string current_data_type;
char* valid_data_types[3] = {"Temperature", "Rho*cp", "Cell_energy"};
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int number_of_lines; /* tells how many data lines follows */



/************************************************************
* conversion loop - continue as long as data-files exists *
************************************************************/

for(unsigned int i=0; i<999; i++)
{

ifstream infile("file", i, ".vtk"); /* file[filenumber].vtk */
if( infile )
{
infile >> read_line;

/* ??? if read_line == one of the "valid_data_types" ...
then begin conversion... Else: read a new line */
/* valid lines beginn with:
"SCALARS" + spc + |current_data_type| + spc */


/* test: cout read_line; */

/* tex_file[filenumber].tex */
ofstream outfile("tex_file", i, ".tex");


/**********************************
* do the actual conversion here *
**********************************/

outfile << LaTeX_header;

/*
for(unsigned int linenumber=1; linenumber<number_of_lines;
linenumber++)
{
infile >> something;
outfile << converted_something;
}
*/

outfile << LaTeX_tail;

}

if( ! infile ) /* can't open file? Then finish */
break;
}


cout << filenumber+1 << " number of .tex files written" << endl << endl;

return 0;
}


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

As you see it's probably very much C-style and not very good C++-style, as I
did my bachelor project in C (and this conversion utility is a continuation
of my bs.c project).

First step: How can I make this compile? Suggestions are most welcome...


I get a lot of strange things when I try to compile... Such as:

/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:43: error: expected
constructor, destructor, or type conversion before ‘namespace’
/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:47: error:
‘__gnu_debug_def’ is not a namespace-name
/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:47: error: expected
namespace-name before ‘;’ token
...... etc. etc...


Best regards
Martin Jørgensen
 
M

Moonlit

Hi,

Well this seems to come from the compiler itself, this means there is
something wrong with it. Just a wild guess; you might try to include the
'#include' s in a different order. If that doesn't work install another
version of g++.


Regards, Ron AF Greve

http://moonlit.xs4all.nl

Martin Jørgensen said:
Hi,

I've had a introductory C++ course in the spring and haven't programmed in
C++ for a couple of months now (but I have been programmed in C since
january). So I decided to do my conversion utility in C++, before I forget
everything. But it doesn't compile:



------------
cat export_tex.C

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


/*************************************************
* *
* This program takes data from some .vtk *
* input-files and exports them to .tex-format *
* *
*************************************************/


int main()
{
/* will contain LaTeX preamble etc */
string LaTeX_header = "test, bla.bla... \n\begin{document}\n";
string LaTeX_tail = "\end{document\n}";

string current_data_type;
char* valid_data_types[3] = {"Temperature", "Rho*cp", "Cell_energy"};
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int number_of_lines; /* tells how many data lines follows */



/************************************************************
* conversion loop - continue as long as data-files exists *
************************************************************/

for(unsigned int i=0; i<999; i++)
{

ifstream infile("file", i, ".vtk"); /* file[filenumber].vtk */
if( infile )
{
infile >> read_line;

/* ??? if read_line == one of the "valid_data_types" ...
then begin conversion... Else: read a new line */
/* valid lines beginn with:
"SCALARS" + spc + |current_data_type| + spc */


/* test: cout read_line; */

/* tex_file[filenumber].tex */
ofstream outfile("tex_file", i, ".tex");


/**********************************
* do the actual conversion here *
**********************************/

outfile << LaTeX_header;

/*
for(unsigned int linenumber=1; linenumber<number_of_lines;
linenumber++)
{
infile >> something;
outfile << converted_something;
}
*/

outfile << LaTeX_tail;

}

if( ! infile ) /* can't open file? Then finish */
break;
}


cout << filenumber+1 << " number of .tex files written" << endl << endl;

return 0;
}


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

As you see it's probably very much C-style and not very good C++-style, as
I
did my bachelor project in C (and this conversion utility is a
continuation
of my bs.c project).

First step: How can I make this compile? Suggestions are most welcome...


I get a lot of strange things when I try to compile... Such as:

/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:43: error:
expected
constructor, destructor, or type conversion before 'namespace'
/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:47: error:
'__gnu_debug_def' is not a namespace-name
/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:47: error:
expected
namespace-name before ';' token
..... etc. etc...


Best regards
Martin Jørgensen
 
M

Moonlit

Hi,

Wait a minute, your file ends with .cc or not? Make sure you compile it with
g++ and not gcc.


Regards, Ron AF Greve

http://moonlit.xs4all.nl

Moonlit said:
Hi,

Well this seems to come from the compiler itself, this means there is
something wrong with it. Just a wild guess; you might try to include the
'#include' s in a different order. If that doesn't work install another
version of g++.


Regards, Ron AF Greve

http://moonlit.xs4all.nl

Martin Jørgensen said:
Hi,

I've had a introductory C++ course in the spring and haven't programmed
in
C++ for a couple of months now (but I have been programmed in C since
january). So I decided to do my conversion utility in C++, before I
forget
everything. But it doesn't compile:



------------
cat export_tex.C

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


/*************************************************
* *
* This program takes data from some .vtk *
* input-files and exports them to .tex-format *
* *
*************************************************/


int main()
{
/* will contain LaTeX preamble etc */
string LaTeX_header = "test, bla.bla... \n\begin{document}\n";
string LaTeX_tail = "\end{document\n}";

string current_data_type;
char* valid_data_types[3] = {"Temperature", "Rho*cp", "Cell_energy"};
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int number_of_lines; /* tells how many data lines follows */



/************************************************************
* conversion loop - continue as long as data-files exists *
************************************************************/

for(unsigned int i=0; i<999; i++)
{

ifstream infile("file", i, ".vtk"); /* file[filenumber].vtk */
if( infile )
{
infile >> read_line;

/* ??? if read_line == one of the "valid_data_types" ...
then begin conversion... Else: read a new line */
/* valid lines beginn with:
"SCALARS" + spc + |current_data_type| + spc */


/* test: cout read_line; */

/* tex_file[filenumber].tex */
ofstream outfile("tex_file", i, ".tex");


/**********************************
* do the actual conversion here *
**********************************/

outfile << LaTeX_header;

/*
for(unsigned int linenumber=1; linenumber<number_of_lines;
linenumber++)
{
infile >> something;
outfile << converted_something;
}
*/

outfile << LaTeX_tail;

}

if( ! infile ) /* can't open file? Then finish */
break;
}


cout << filenumber+1 << " number of .tex files written" << endl << endl;

return 0;
}


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

As you see it's probably very much C-style and not very good C++-style,
as I
did my bachelor project in C (and this conversion utility is a
continuation
of my bs.c project).

First step: How can I make this compile? Suggestions are most welcome...


I get a lot of strange things when I try to compile... Such as:

/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:43: error:
expected
constructor, destructor, or type conversion before 'namespace'
/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:47: error:
'__gnu_debug_def' is not a namespace-name
/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:47: error:
expected
namespace-name before ';' token
..... etc. etc...


Best regards
Martin Jørgensen
 
M

Michael

....

First step: How can I make this compile? Suggestions are most welcome...

It's complaining about the word "using," which is C++ specific.

My guess - change the filename to .CC or .cc or .cpp or something like
that. At least a couple of compilers I've used have a heuristic that
checks filename and compiles in C mode or C++ mode depending. And be
sure you're using the C++ version of the compiler (g++ instead of gcc).

I tried compiling in VS, and it complains, but not about that.

Michael
 
T

Thomas Tutone

Martin said:
Hi,

I've had a introductory C++ course in the spring and haven't programmed in
C++ for a couple of months now (but I have been programmed in C since
january). So I decided to do my conversion utility in C++, before I forget
everything. But it doesn't compile:



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

#include <iostream>
#include <fstream>
#include <string>

using namespace std;


/*************************************************
* *
* This program takes data from some .vtk *
* input-files and exports them to .tex-format *
* *
*************************************************/


int main()
{
/* will contain LaTeX preamble etc */
string LaTeX_header = "test, bla.bla... \n\begin{document}\n";
string LaTeX_tail = "\end{document\n}";

Keep in mind that C++ uses "\" as an escape character, so the above
line probably doesn't do what you expect.

string current_data_type;
char* valid_data_types[3] = {"Temperature", "Rho*cp", "Cell_energy"};
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int number_of_lines; /* tells how many data lines follows */



/************************************************************
* conversion loop - continue as long as data-files exists *
************************************************************/

for(unsigned int i=0; i<999; i++)
{

ifstream infile("file", i, ".vtk"); /* file[filenumber].vtk */

The above line does not use a valid constructor for ifstream.
ifstream's constructor is declared as follows:

explicit basic_ifstream(const char *filename, ios_base::eek:penmode mode =
ios_base::in);

In other words, your three argument constructor isn't valid, AFAIK.

if( infile )
{
infile >> read_line;

/* ??? if read_line == one of the "valid_data_types" ...
then begin conversion... Else: read a new line */
/* valid lines beginn with:
"SCALARS" + spc + |current_data_type| + spc */


/* test: cout read_line; */

/* tex_file[filenumber].tex */
ofstream outfile("tex_file", i, ".tex");


/**********************************
* do the actual conversion here *
**********************************/

outfile << LaTeX_header;

/*
for(unsigned int linenumber=1; linenumber<number_of_lines;

You never initialized number_of_lines.

That's a start, anyway.

Best regards,

Tom
 
P

Phlip

Is this C or C++? Sometimes compilers trigger on the filename suffix, so see
if that fixes it.

(However, your compiler's forum is the best place for subsequent questions
on how to drive it...)
I get a lot of strange things when I try to compile... Such as:

/usr/include/c++/4.1.0/i586-suse-linux/bits/c++config.h:43: error:
expected
constructor, destructor, or type conversion before 'namespace'

A 'config.h' is often the very first header file of any translation unit,
because (again, off-topically) many compilers rely on install scripts that
build config.h with their platform-specific details.

However, your compiler can't understand its first C++ line. Maybe the
compiler is in C mode, and then maybe the error message incorrectly
specifies C things.

Alternately, maybe your compiler is old and doesn't understand namespaces,
which are new. Try these:

$ which c++

That might show a path with a version other than 4.1

$ ls -l `which c++`

That might show a link to path with a version other than 4.1

$ c++ -v

And that might show version info other than 4.1.

And, naturally, you might be calling some wrapper other than c++, such as
g++. Check your makefile.
 
M

Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=

Thomas Tutone wrote:

-snip-
Keep in mind that C++ uses "\" as an escape character, so the above
line probably doesn't do what you expect.

Thanks. I think \\ must be the correct thing then.

-snip-
for(unsigned int i=0; i<999; i++)
{

ifstream infile("file", i, ".vtk"); /* file[filenumber].vtk */

The above line does not use a valid constructor for ifstream.
ifstream's constructor is declared as follows:

explicit basic_ifstream(const char *filename, ios_base::eek:penmode mode =
ios_base::in);

In other words, your three argument constructor isn't valid, AFAIK.

Damn... I wanted the loop to process these file names:

file000.vtk
file001.vtk
file002.vtk
file003.vtk
.....
.....

So that explains the "file" + the counter in the loop, "i", + extension. How
to do this, then? And my original suggestion also didn't take into account
that the numbers should always take up 3 characters. Here's my
C-implementation (this is how I make the output filenames in C):


--- for-loop --
if(*filecounter >999)
{
printf("Error! Too many results have been written.\n\n");
quit_program(__FILE__, __LINE__);
}

sprintf(fname, "file_%03d.vtk", *file_counter);
---


How to this in C++? - In an "elegant" way, ofcourse...

Here I want to read a line... Not sure I did it correctly...

I must compare the beginning of each line with the word "SCALARS". Once I
find that word in the beginning of a line, I must see if it's one of the 3
char *valid_data_types[3].

-snip-
You never initialized number_of_lines.

That's a start, anyway.

You're right, thanks... The number of lines is something I'll have to
extract from inside the data-file and I haven't exactly figured out how to
do that yet...


I can now compile my program. I had a stupid "x" in the top of the file and
after I removed the ifstream infile("file", i, ".vtk") line (and also for
the ofstream) I got something usable:

Complete program follows:
------------------------
cat output_to_latex.cpp
#include <iostream>
#include <fstream>
#include <string>

using namespace std;


/*************************************************
* *
* This program takes data from some .vtk *
* input-files and exports them to .tex-format *
* *
*************************************************/


int main()
{
/* will contain LaTeX preamble etc */
string LaTeX_header = "test, bla.bla... \n\\begin{document}\n";
string LaTeX_tail = "\\end{document}\n";

string current_data_type;
char* valid_data_types[3] = {"Temperature", "Rho*cp", "Cell_energy"};
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int number_of_lines; /* tells how many data lines follows */



/************************************************************
* conversion loop - continue as long as data-files exists *
************************************************************/

for(unsigned int i=0; i<999; i++)
{

ifstream infile("file000.vtk");
// ifstream infile("file", i, ".vtk"); /* file[filenumber].vtk */

if( infile )
{
infile >> read_line;

/* ??? if read_line == one of the "valid_data_types" ...
then begin conversion... Else: read a new line */
/* valid lines beginn with:
"SCALARS" + spc + |current_data_type| + spc */


/* test: cout read_line; */
ofstream outfile("tex_file000.tex");
/* should be tex_file[filenumber].tex, something like:
ofstream outfile("tex_file", i, ".tex"); */


/**********************************
* do the actual conversion here *
**********************************/

outfile << LaTeX_header;

/*
for(unsigned int linenumber=1; linenumber<number_of_lines;
linenumber++)
{
infile >> something;
outfile << converted_something;
}
*/

outfile << LaTeX_tail;

}

if( ! infile ) /* can't open file? Then finish */
break;
}


cout << filenumber+1 << " number of .tex files written" << endl << endl;

return 0;
}

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

Suggestions are welcome... I probably should make a file-class and then have
a smaller main-function with a loop that just increments the file-counter
and calls some function in that class... or something...

I still have a few problems to solve...


Best regards
Martin Jørgensen
 
M

Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=

Phlip said:
Is this C or C++? Sometimes compilers trigger on the filename suffix, so
see if that fixes it.

I've read that .c is C and .C is C++ on unix... And it didn't make any
difference to use .cpp, but now I use .cpp even though it isn't necessary.



Best regards
Martin Jørgensen
 
B

BobR

Michael wrote in message
It's complaining about the word "using," which is C++ specific.

My guess - change the filename to .CC or .cc or .cpp or something like
that. At least a couple of compilers I've used have a heuristic that
checks filename and compiles in C mode or C++ mode depending. And be
sure you're using the C++ version of the compiler (g++ instead of gcc).

[ GCC Docs ]
For any given input file, the file name suffix determines what kind of
compilation is done:

file.c
C source code which must be preprocessed.
[ use gcc ]

file.cc
file.cp
file.cxx
file.cpp
file.c++
file.C
C++ source code which must be preprocessed. Note that in .cxx, the last
two
letters must both be literally x. Likewise, .C refers to a literal
capital C.
[ use g++ ]
 
B

BobR

Martin Jørgensen wrote in message
<[email protected]>...
Thomas Tutone wrote:

-snip-
Thanks. I think \\ must be the correct thing then.
Yup!

-snip-
for(unsigned int i=0; i<999; i++){
ifstream infile("file", i, ".vtk"); /* file[filenumber].vtk */

The above line does not use a valid constructor for ifstream.
In other words, your three argument constructor isn't valid, AFAIK.
Damn... I wanted the loop to process these file names:
file000.vtk
file001.vtk
file002.vtk
file003.vtk
....
/* "
So that explains the "file" + the counter in the loop, "i", + extension. How
to do this, then?
And my original suggestion also didn't take into account
that the numbers should always take up 3 characters. Here's my
C-implementation (this is how I make the output filenames in C):

How to this in C++? - In an "elegant" way, ofcourse...
" */

One way is to use 'stringstream' (header <sstream>), then put it in a
std::string.

#include <string>
#include <sstream> // for std::eek:stringstream
#include <iomanip> // for std::setfill(), std::setw()

int fnumb(5); // you will use the 'int' in your for loop.
std::eek:stringstream Oss;
Oss << "file" <<std::setfill( '0' )<<std::setw( 3 )<< fnumb << ".vtk";
std::string Filename;
Filename = Oss.str();
// or just: std::string Filename( Oss.str() );

std::cout<<" Filename ="<<Filename<<std::endl;
// --- output ---
// Filename =file005.vtk

ifstream infile( Filename.c_str() ); /* file[filenumber].vtk */

Here I want to read a line... Not sure I did it correctly...

std::string read_line;

std::getline( infile, read_line );
I must compare the beginning of each line with the word "SCALARS". Once I
find that word in the beginning of a line, I must see if it's one of the 3
char *valid_data_types[3].

std::string FindThis( "SCALARS" );
if( read_line.find( FindThis ) != std::string::npos ){
/* "SCALARS" is in read_line */
std::string FindThis1( valid_data_types[0] ); // may need 'adjusting'
(*)
if( read_line.find( FindThis1 ) != std::string::npos ){
/* valid_data_types[0] is in read_line */
}
}



Read-up on std::string and std::streams, then you'll have much power at your
command! <G>

Hope that helps. This ain't homework is it?
 
M

Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=

BobR wrote:

-snip-
Read-up on std::string and std::streams, then you'll have much power at
your command! <G>

Hope that helps. This ain't homework is it?

Nope. No teacher gives me any homework that extends my bs.c. project because
I'm not a software/electrical engineer or something like that. I'm a
mechanical engineer (studying to get my masters degree) so the only thing
the teachers want is Matlab programming. This is just so I don't forget all
I learned about c++.

I took your suggestions and implemented some of it and rewrote everything...
It's much more C++'ish, but I can't compile it...

Just copy/paste, compile and tell me your suggestions.


----- unfinished code begins ----
#include <iostream>
#include <fstream>
#include <string>
#include <sstream> /* for std::eek:stringstream */
#include <iomanip> /* for std::setfill(), std::setw() */
#include <vector>
#include <ctype.h> /* for isspace */

using namespace std;


std::string trim( std::string const& s )
{
// Create string from first non-whitespace to last non-whitespace

return std::string ( std::find_if( s.begin(), s.end(), std::not
(std::ptr_fun(&isspace) ) ),
std::find_if( s.rbegin(), s.rend(), std::not
(std::ptr_fun(&isspace) ) ).base() );

}

/*****************************************************/

void convert_data(unsigned int linenumber,
const string &cur_ifilename, const string &cur_ofilename)
{

string LaTeX_header = "test, bla.bla... \n\\begin{document}\n";
string LaTeX_tail = "\\end{document}\n";

/***********************************
* do the actual conversion here *
***********************************/

// ofstream outfile( cur_ofilename::c_str() ); <<<< WRONG???

// outfile << LaTeX_header;
/*
for(unsigned int linenumber=1; linenumber<number_of_lines; linenumber++)
{
infile >> something;
outfile << converted_something;
}
*/
// outfile << LaTeX_tail;
}

/*****************************************************/

void set_file_names(unsigned int filenumber, string &cur_ifilename,
string &cur_ofilename)
{

/*************************
* Creating file names *
*************************/

ostringstream filename_generated;

filename_generated << "file" << setfill('0') <<
setw(3) << filenumber << ".vtk";
cur_ifilename = filename_generated.str();
filename_generated << "tex_file" << setfill('0') <<
setw(3) << filenumber << ".tex";

/* WRONG!!! = file000.vtktex_file000.tex ??? */
cur_ofilename = filename_generated.str();

cout << "Input filename = " << cur_ifilename << endl;
cout << "Output filename = " << cur_ofilename << endl;
}

/*****************************************************/

int main()
{
string current_data_type;
vector<string> possible_data_types;
int data_type;
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int linenumber; /* current line */
unsigned int number_of_lines; /* how many data lines follows */

string cur_ifilename; /* input */
string cur_ofilename; /* output */



/*******************************************************
* scan the first input file for possible data types *
*******************************************************/

set_file_names(0, cur_ifilename, cur_ofilename);

ifstream infile( cur_ifilename.c_str() );
while( infile )
{
getline( infile, read_line);

if( read_line.find("SCALARS") != string::npos )
{
/* "SCALARS" was found in read_line */
cout << read_line << endl;

/* "SCALARS" + spc + |current_data_type| + spc */
current_data_type = trim( read_line );
cout << current_data_type << endl;
possible_data_types.push_back(current_data_type);
}
}


/*********************************************
* ask which data type should be converted *
********************************************/
data_type = 0;
for( vector<string::const_iterator it = possible_data_types.begin();
it != possible_data_types.end(); ++it)
{
cout << data_type << ": " << possible_data_types(*it) << endl;
}
cout << endl << "Which datatype (number) should be converted ? ";
cin >> data_type;

current_data_type = possible_data_types[data_type];



/*******************************
* convert data in all files *
*******************************/

for(unsigned int filenumber=0; filenumber<999; filenumber++)
{

set_file_names(filenumber, cur_ifilename, cur_ofilename);

linenumber = 0;
ifstream infile( cur_ifilename.c_str() );

while( infile )
{

linenumber++; /* counter for debugging */
getline( infile, read_line);

if( read_line.find("SCALARS") != string::npos )
{
/* "SCALARS" was found in read_line */
cout << read_line << endl; /* debug */

/* if( read_line contains "current_data_type" - convert)
/* "SCALARS" + spc + |current_data_type| + spc */

convert_data( linenumber, cur_ifilename, cur_ofilename);

cout << "Program not finished. Come back later" << endl;
return 1;
}


cout << "Program not finished. Come back later" << endl;
return 1;
}
}


cout << filenumber+1 << " number of .tex files written" << endl << endl;
return 0;
}

----- unfinished code ends ----


Best regards
Martin Jørgensen
 
B

BobR

Martin Jørgensen wrote in message
<[email protected]>...
BobR wrote:

-snip-

Good. We don't like to do the homework for someone, but rather, guide a
student.
I like to play with code, so I usually leave the homework to the guys higher
I took your suggestions and implemented some of it and rewrote everything...
It's much more C++'ish, but I can't compile it...


Just copy/paste, compile and tell me your suggestions.

I'll check out your code in a little bit. I just wanted to mention the below:
----- unfinished code begins ----
// #include <ctype.h> /* for isspace */

// For C++ you want to use:
#include <cctype> /* for isspace */

This will put all those things in 'ctype' in the 'std::' namespace. You won't
have to change any of your code because you are using 'using namespace std;'.
(otherwise you would use 'std::isspace()'.)


/*****************************************************/
void convert_data(unsigned int linenumber,
const string &cur_ifilename, const string &cur_ofilename){

// ofstream outfile( cur_ofilename::c_str() ); <<<< WRONG???

ofstream outfile( cur_ofilename.c_str() ); // change the qualifier '::' to
dot '.'
// note: ah, I see you did it correctly below.
<snip>



/* """ // note: this is my way of 'quoting' since my newsreader doesn't
// do it for me (you are posting from a *nix machine?)

/*****************************************************/
void set_file_names(unsigned int filenumber, string &cur_ifilename,
string &cur_ofilename){
/*************************
* Creating file names *
*************************/
ostringstream filename_generated;

filename_generated << "file" << setfill('0') <<
setw(3) << filenumber << ".vtk";
cur_ifilename = filename_generated.str();
filename_generated << "tex_file" << setfill('0') <<
setw(3) << filenumber << ".tex";
/* WRONG!!! = file000.vtktex_file000.tex ??? */
cur_ofilename = filename_generated.str();

""" */

// OK, when you want to 're-use' a stream you need to 'clear' it:

ostringstream filename_generated;

filename_generated << "file" << setfill('0') <<
setw(3) << filenumber << ".vtk";
cur_ifilename = filename_generated.str();

// -- add this here: --
filename_generated.str(""); // 'clear' the stream
filename_generated.clear(); // and 'reset' the stream

filename_generated << "tex_file" << setfill('0') <<
setw(3) << filenumber << ".tex";
cur_ofilename = filename_generated.str();

cout << "Input filename = " << cur_ifilename << endl;
cout << "Output filename = " << cur_ofilename << endl;
} // set_file_names(unsigned int, string &, string &) end


/* """

/*****************************************************/
int main(){
string current_data_type;
vector<string> possible_data_types;
int data_type;
string read_line;
unsigned int filenumber; /* current data file number */
unsigned int linenumber; /* current line */
unsigned int number_of_lines; /* how many data lines follows */
string cur_ifilename; /* input */
string cur_ofilename; /* output */
/*******************************************************
* scan the first input file for possible data types *
*******************************************************/
set_file_names(0, cur_ifilename, cur_ofilename);
ifstream infile( cur_ifilename.c_str() );
while( infile ) {
getline( infile, read_line);

""" */

// Try it this way:

ifstream infile( cur_ifilename.c_str() );
if( not infile ){ /* handle error here */}

while( getline( infile, read_line) ) {
// ......
} // while(getline)


That should clear-up a few things. I'll post again after I 'check-out' your
code.

You may be interested in a little header I've been playing with. It ain't
perfect, but, has worked for everything I threw at it.
[ assume your file is not super-big (will fit in memory) ]

// -------------------------------------------------------
// Filer.h
// -------------------------------------------------------
#ifndef Filer_H
#define Filer_H
// ----------------------------------------------
#include <iostream>
#include <ostream> // std::endl
#include <string>
#include <vector>
#include <fstream>
// --------------------------------------
#include <stdexcept>
class FilerErr : public std::runtime_error { public:
FilerErr(const std::string& msg = "") : std::runtime_error(msg){}
};
//use: try{ throw FilerErr(__FILE__": my message");}
// --------------------------------------
// note: AFAIK vector does not have a virtual destructor, so,
// *never* use this class thru a base pointer.

class Filer : public std::vector<std::string> {
public:
// Filer(){}
Filer(const char *filename) { Open(filename); }
private: // public: if I use Filer() Ctor. Or, 2nd file open
void Open(const char *filename) throw(FilerErr){
std::ifstream in(filename);
if(!in){ throw FilerErr(__FILE__": Open SonOfABitch! ");}
//if(!in)
for( std::string line; std::getline(in, line); ){
push_back(line);
}
return;
} //Open(const char*) throw(MyError)
public:
void Write(std::eek:stream& out = std::cout) throw(FilerErr){
if(!out){ throw FilerErr(__FILE__": Write SonOfABitch! ");}
//if(!in)
for(const_iterator w = begin(); w != end(); ++w)
out << *w << std::endl;
} //Write(ostream&)
}; //class Filer
// -------------------------------------------------------
#endif //#ifndef Filer_H


// --- TestFiler.cpp ---
// ----------------------------------------------
#include <iostream> // just in case<G>
#include <fstream>
#include <string> // just in case<G>
#include "Filer.h"

int main(){
using std::cout; // for NG posting
try{
cout<<"_____ Filer.h test _____"<<std::endl;
Filer Afile("Filer.h");
// Filer Afile("ErrFiler.h"); // to test exception.
Afile.Write( cout );
cout<<"\nAfile.size()="<<Afile.size()<<" lines."<<std::endl;
cout<<"Afile.at(1)="<<Afile.at(1)<<std::endl;

std::string FindThis( "// *never* use this class thru a base
pointer." );
// - the following works, but, needs 'fixing' <G> -
Filer::iterator FindMain = Afile.begin();
for(size_t a(0); a < Afile.size(); ++a){
if( Afile.at(a).find( FindThis ) != std::string::npos ){
FindMain = Afile.begin() + a;
}
} // for(a)
Afile.insert(FindMain, "//__________ inserted line __________");
Afile.push_back("\n//----- This is a copy -----");
std::eek:fstream Ofile("CopyFiler.txt");
if( !Ofile){ return EXIT_FAILURE; }
Afile.Write( Ofile );
cout<<"_____ Filer.h test End _____"<<std::endl;
} // try{}
catch(FilerErr &x){
cout<<"FilerErr &x.what()="<< x.what() <<std::endl;
} // catch(FilerErr&)
catch(std::eek:ut_of_range &Oor){
cout<<"\ncaught "<<Oor.what()<<std::endl;
}
catch(...){
cout<< "\ncaught something!!" <<std::endl;
} //catch(MyError&)
return 0;
} //main()
// -----------------------------------------------------------------END
 
M

Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=

BobR wrote:
-snip-
// For C++ you want to use:
#include <cctype> /* for isspace */
Thanks.

-snip-
// ofstream outfile( cur_ofilename::c_str() ); <<<< WRONG???

ofstream outfile( cur_ofilename.c_str() ); // change the qualifier '::'
to
dot '.'
// note: ah, I see you did it correctly below.

Dough.... Thanks...
/* """ // note: this is my way of 'quoting' since my newsreader doesn't
// do it for me (you are posting from a *nix machine?)

Yes, I try to learn to use emacs and the linux utilities on my suse 10.1
laptop machine and sometimes the compiler complains if I use
"old-fashioned" // for comments so I manually change all comments to /*
*/-style...


-snip-
// OK, when you want to 're-use' a stream you need to 'clear' it:

ostringstream filename_generated;

filename_generated << "file" << setfill('0') <<
setw(3) << filenumber << ".vtk";
cur_ifilename = filename_generated.str();

// -- add this here: --
filename_generated.str(""); // 'clear' the stream
filename_generated.clear(); // and 'reset' the stream

Thanks! Very nice... Exactly what I couldn't solve myself...

-snip-
// Try it this way:

ifstream infile( cur_ifilename.c_str() );
if( not infile ){ /* handle error here */}

while( getline( infile, read_line) ) {
// ......
} // while(getline)


That should clear-up a few things. I'll post again after I 'check-out'
your code.

Thanks a lot... That was also a great suggestion as it clears things a bit
up...
You may be interested in a little header I've been playing with. It ain't
perfect, but, has worked for everything I threw at it.
[ assume your file is not super-big (will fit in memory) ]
-snip-

I just quickly tried to compile it and it runs fine... I've always wanted to
learn more about this try/catch-thing. So this program is really great for
that, I think... See my other reply, which I'll post shortly...

Summary: I think I'm almost done with the hardest part, but I only get a
single output-file written out............... Do you have any idea why?


--------- program that's much better than I started out with ------------
#include <iostream>
#include <fstream>
#include <string> /* for string manipulations */
#include <sstream> /* for std::eek:stringstream */
#include <iomanip> /* for std::setfill(), std::setw() */
#include <vector> /* sequential container */
#include <cctype> /* for isspace */


using namespace std;


/**************************************************
* *
* This program takes data from some .vtk *
* input-files and exports them to .tex-format *
* *
**************************************************/


/*****************************************************/

std::string trim(std::string str)
{
string::size_type pos = str.find_last_not_of(' ');

if(pos != string::npos)
{
str.erase(pos + 1);
pos = str.find_first_not_of(' ');
if(pos != string::npos)
str.erase(0, pos);
}
else
str.erase(str.begin(), str.end());

return str;
}


/*****************************************************/

void convert_data(unsigned int linenumber,
const string &cur_ifilename, const string &cur_ofilename)
{

string LaTeX_header = "\\begin{document}\n";
string LaTeX_tail = "\\end{document}\n";

/***********************************
* do the actual conversion here *
***********************************/

ofstream outfile( cur_ofilename.c_str() );

outfile << LaTeX_header;
/*
for(unsigned int linenumber=1; linenumber<number_of_lines; linenumber++)
{
infile >> something;
outfile << converted_something;
}
*/
outfile << LaTeX_tail;
}

/*****************************************************/

void set_file_names(unsigned int filenumber, string &cur_ifilename,
string &cur_ofilename)
{

/*************************
* Creating file names *
*************************/

ostringstream filename_generated;

filename_generated << "file" << setfill('0') <<
setw(3) << filenumber << ".vtk";
cur_ifilename = filename_generated.str();

filename_generated.str(""); /* clear stream */
filename_generated.clear(); /* reset it */

filename_generated << "tex_file" << setfill('0') <<
setw(3) << filenumber << ".tex";

cur_ofilename = filename_generated.str();
}

/*****************************************************/

int main()
{
string current_data_type;
vector<string> possible_data_types;
int data_type;
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int linenumber; /* current line */
unsigned int number_of_lines; /* how many data lines follows */

string cur_ifilename; /* input */
string cur_ofilename; /* output */


/*******************************************************
* scan the first input file for possible data types *
*******************************************************/

set_file_names(0, cur_ifilename, cur_ofilename);

ifstream infile( cur_ifilename.c_str() );


if( not infile )
{
cout << "\n\nERROR!\n**********\nCouln't open file " << cur_ifilename
<< endl;
return 1;
}


while( getline( infile, read_line) )
{

if( read_line.find("SCALARS") != string::npos )
{
/* "SCALARS" was found in read_line */

/* "SCALARS" + spc + |current_data_type| + spc */
// remove the word SCALARS from read_line ?!?!
current_data_type = trim( read_line );

/* I can't figure out how to trim the line correctly */
possible_data_types.push_back(current_data_type);
}
}


/*********************************************
* ask which data type should be converted *
********************************************/

cout << "*******************************************" << endl;
data_type = 0;
for( vector<string>::const_iterator it = possible_data_types.begin();
it != possible_data_types.end(); ++it)
{
data_type++;
cout << data_type << ": " << *it << endl;
}
cout << endl << "Which datatype (number) should be converted ? ";
cin >> data_type;

current_data_type = possible_data_types[data_type-1];



/*******************************
* convert data in all files *
*******************************/

for(filenumber=0; filenumber<999; filenumber++)
{

set_file_names(filenumber, cur_ifilename, cur_ofilename);

linenumber = 0;
ifstream infile( cur_ifilename.c_str() );

if( infile )
{

linenumber++; /* counter for debugging */
getline( infile, read_line);

if( read_line == current_data_type )
{
cout << read_line << endl; /* debug */

convert_data( linenumber, cur_ifilename, cur_ofilename);
}
}
else
break;
}


cout << endl << filenumber+1 << " number of .tex files written" << endl <<
endl;
return 0;
}
 
M

Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=

BobR wrote:

-snip-
// --- TestFiler.cpp ---
// ----------------------------------------------
#include <iostream> // just in case<G>
#include <fstream>
#include <string> // just in case<G>
#include "Filer.h"

int main(){
using std::cout; // for NG posting
try{
cout<<"_____ Filer.h test _____"<<std::endl;
Filer Afile("Filer.h");
// Filer Afile("ErrFiler.h"); // to test exception.
Afile.Write( cout );
cout<<"\nAfile.size()="<<Afile.size()<<" lines."<<std::endl;
cout<<"Afile.at(1)="<<Afile.at(1)<<std::endl;


Okay, so far so good.... But what does the following do?

std::string FindThis( "// *never* use this class thru a base
pointer." );

I can't remember that, although I learned something about that... Do you
have a small example of what *not* to do here?
// - the following works, but, needs 'fixing' <G> -
Filer::iterator FindMain = Afile.begin();
for(size_t a(0); a < Afile.size(); ++a){
if( Afile.at(a).find( FindThis ) != std::string::npos ){
FindMain = Afile.begin() + a;
}
} // for(a)
Afile.insert(FindMain, "//__________ inserted line __________");
Afile.push_back("\n//----- This is a copy -----");
std::eek:fstream Ofile("CopyFiler.txt");
if( !Ofile){ return EXIT_FAILURE; }
Afile.Write( Ofile );

Hmm... The above code... Perhaps it's a stupid question, but what does it
do? The catch-part below, I think is easy to understand...


Best regards
Martin Jørgensen
 
B

BobR

Martin Jørgensen wrote in message
<[email protected]>...
BobR wrote:

-snip-
Okay, so far so good.... But what does the following do?

It just 'initialises' the string 'FindThis' to the text to search for.

std::string FindThis( "Hi." ); // initialization
// accomplishes the same thing as:
std::string FindThis;
FindThis = "Hi."; // assignment

I can't remember that, although I learned something about that... Do you
have a small example of what *not* to do here?

For a std::string or my class 'Filer'?
For 'Filer', you NEVER want to do this:

std::vector<std::string> *MyPointer = new Filer("somefile.txt");

If 'std::vector' had a virtual destructor, you might get away with it (for
simplicity here, just think that an vector::iterator is a pointer. So, don't
do that either.). It can cause a memory leak due to 'slicing' (corrections by
experts are welcome.<G>).

Filer *MyPointer = new Filer("somefile.txt");
....should/*might* work, but, that's not what I intended. I keep the class
simple for simple use.


/* """
// - the following works, but, needs 'fixing' <G> -
Filer::iterator FindMain = Afile.begin();
for(size_t a(0); a < Afile.size(); ++a){
if( Afile.at(a).find( FindThis ) != std::string::npos ){
FindMain = Afile.begin() + a;
}
} // for(a)
Afile.insert(FindMain, "//__________ inserted line __________");
Afile.push_back("\n//----- This is a copy -----");
std::eek:fstream Ofile("CopyFiler.txt");
if( !Ofile){ return EXIT_FAILURE; }
Afile.Write( Ofile );
""" */
Hmm... The above code... Perhaps it's a stupid question, but what does it
do? The catch-part below, I think is easy to understand...

It demonstrates searching through a file ("Filer.h") for a certain text
('FindThis'). Then it 'inserts' a line into the vector (class 'Filer' is
derived from a std::vector, so, it acts like a vector.). Then it adds a line
"-- This is a copy --" to the end (using 'push_back()').
Then it writes the vector out to a file "CopyFiler.txt". You can open that
file in any text editor to verify that the original file and the new file are
different.

Does that 'splain enough?
 
B

BobR

Martin Jørgensen wrote in message
<[email protected]>...
BobR wrote:
-snip-
Summary: I think I'm almost done with the hardest part, but I only get a
single output-file written out............... Do you have any idea why?
--------- program that's much better than I started out with ------------

std::string trim(std::string str){
if(pos != string::npos){
}
else
str.erase(str.begin(), str.end());

Did you intend to erase the whole string?
Just use:
str.clear();
return str;
}

/* """

/*****************************************************/
void convert_data(unsigned int linenumber,
const string &cur_ifilename, const string &cur_ofilename){
string LaTeX_header = "\\begin{document}\n";
string LaTeX_tail = "\\end{document}\n";
/***********************************
* do the actual conversion here *
***********************************/
ofstream outfile( cur_ofilename.c_str() );
outfile << LaTeX_header;
/*
for(unsigned int linenumber=1; linenumber<number_of_lines; linenumber++){
infile >> something;
outfile << converted_something;
}
*/
outfile << LaTeX_tail;
}

""" */


/*****************************************************/
int main(){
<snip>

/* I can't figure out how to trim the line correctly */

Show us a line, and what you want it to look like.
( put the lines in quotes ("") so we can see the spaces. )


/* """
// ref: string current_data_type;
current_data_type = possible_data_types[data_type-1];
/*******************************
* convert data in all files *
*******************************/
for(filenumber=0; filenumber<999; filenumber++){
set_file_names(filenumber, cur_ifilename, cur_ofilename);
linenumber = 0;
ifstream infile( cur_ifilename.c_str() );
if( infile ){
linenumber++; /* counter for debugging */
getline( infile, read_line);


if( read_line == current_data_type ){

""" */

I think that last line is NOT what you want! Is there a possibility that
there is more than one 'data_type' in a single line?
If not, you may want:

if( read_line.find( current_data_type ) != string::npos ){ /* ... */ }

You were comparing two strings for equality.

std::string Line1("this is a line of text.");
std::string Line2("text");
if( Line1 == Line2 ){
// will never execute this line
}

cout << read_line << endl; /* debug */
convert_data( linenumber, cur_ifilename, cur_ofilename);
}

At least I can see you are makeing progress! <G>
Don't be afraid to put in more 'std::cout', you can easily remove them in
your final effort.
Also, work on one thing at a time. Get one function working good, then work
on the next one.
[ Dang, I wish I could follow my own advice!!<G> ]
 
M

Martin =?UTF-8?B?SsO4cmdlbnNlbg==?=

BobR wrote:
-snip-
/* I can't figure out how to trim the line correctly */

Show us a line, and what you want it to look like.
( put the lines in quotes ("") so we can see the spaces. )

I think it works now, so I might just have one problem left... I hope... See
below...
/* """
// ref: string current_data_type;
current_data_type = possible_data_types[data_type-1];
/*******************************
* convert data in all files *
*******************************/
for(filenumber=0; filenumber<999; filenumber++){
set_file_names(filenumber, cur_ifilename, cur_ofilename);
linenumber = 0;
ifstream infile( cur_ifilename.c_str() );
if( infile ){
linenumber++; /* counter for debugging */
getline( infile, read_line);


if( read_line == current_data_type ){

""" */

I think that last line is NOT what you want! Is there a possibility that
there is more than one 'data_type' in a single line?

Yes, there are many "SCALARS" entries, see output below...
If not, you may want:

if( read_line.find( current_data_type ) != string::npos ){ /* ... */
}

You were comparing two strings for equality.

Actually this is okay, because I was lucky and figured out that the user
could just choose from this vector<string> menu, like below:

-------

Deleting old data files...

*******************************************
From initial data file: number_of_lines = 905

1: SCALARS Temperature double 1
2: SCALARS Porosities double 1
3: SCALARS RhoCp double 1
4: SCALARS Cell_energy double 1
5: SCALARS Residuals double 1
6: SCALARS Solidification_time double 1
7: SCALARS h0 double 1
8: SCALARS hx double 1
9: SCALARS hy double 1
10: SCALARS rx double 1
11: SCALARS ry double 1
12: SCALARS area_porosity_X double 1
13: SCALARS area_porosity_Y double 1
14: SCALARS HTC_interface_length double 1

Which datatype (number) should be converted ? 4
SCALARS Cell_energy double 1
SCALARS Cell_energy double 1
SCALARS Cell_energy double 1
SCALARS Cell_energy double 1
SCALARS Cell_energy double 1

5 number of .TeX files written
-------

So I was lucky because all the "SCALARS" lines (shown above) are in all the
input files so I can just compare two strings for equality and when they're
equal, I know that this is the data-type I want to export and I should then
consider the numbers immediately below that line/location...

But I agree, that wasn't clear because I didn't told that so nobody could
know that...


-snip-
Also, work on one thing at a time. Get one function working good, then
work on the next one.
[ Dang, I wish I could follow my own advice!!<G> ]

LOL... Yep, I agree... But I have one problem left, I think... My program
doesn't compile now (error in void convert_data()-function):

After that I think/I hope I'm done and then I think I would like to sit and
play around with you try/catch program :)

----------------
#include <iostream>
#include <fstream> /* for file functions */
#include <string> /* for string manipulations */
#include <sstream> /* for std::eek:stringstream */
#include <iomanip> /* for std::setfill(), std::setw() */
#include <vector> /* sequential container */
#include <cctype> /* for isspace */


using namespace std;


/*****************************************************/

std::string trim(std::string str)
{

string::size_type pos = str.find_first_not_of(' ');
if(pos != string::npos)
str.erase(0, pos);

pos = str.find(' ');
if(pos != string::npos)
str.erase(pos);

return str;
}

/*****************************************************/

void convert_data(unsigned int &linenumber, const unsigned int
&number_of_lines,
const ifstream &infile, const string &cur_ofilename)
{
double read_value;

string LaTeX_header = "\\documentclass{article}\n....";
string LaTeX_tail = " \\end{tabular}}\n\n\\end{document}\n\n";

/***********************************
* do the actual conversion here *
***********************************/

ofstream outfile( cur_ofilename.c_str() ); /* open output-file */

outfile << LaTeX_header;
for(unsigned int line=1; linenumber<number_of_lines; linenumber++)
{
linenumber++;

/* **************************************************
OKAY: When I come to this point the input file looks like:
---
SCALARS something double 1
543.2
342.1
123.5
643.2
....
etc.
----

I want to read the number: 543.2 into a variable, such as read_value, but I
get compiler error...

In function ‘void convert_data(unsigned int&, const unsigned int&, const
std::ifstream&, const std::string&)’:
output_to_latex.cpp:67: error: no matching function for call to
‘std::basic_ifstream<char, std::char_traits<char> >::getline(std::string&)
const’
......***********************************************
*/
string read_line; // <<<<<<<<<<<-------- ERROR
infile.getline( read_line ); // <<<<<<<<<<<-------- ERROR
infile >> read_value;

// outfile << converted_something;
}

outfile << LaTeX_tail;
outfile.close(); /* close it */

}

/*****************************************************/

void set_file_names(unsigned int filenumber, string &cur_ifilename,
string &cur_ofilename, string &current_data_type)
{

/*************************
* Creating file names *
*************************/

ostringstream filename_generated;

filename_generated << "file" << setfill('0') <<
setw(3) << filenumber << ".vtk";
cur_ifilename = filename_generated.str();

filename_generated.str(""); /* clear stream */
filename_generated.clear(); /* reset it */

filename_generated << current_data_type << setfill('0') <<
setw(3) << filenumber << ".tex";

cur_ofilename = filename_generated.str();
}

/*****************************************************/

int main()
{
string current_data_type;
vector<string> possible_data_types;
int data_type;
string read_line;

unsigned int filenumber; /* current data file number */
unsigned int linenumber; /* current line */
unsigned int number_of_lines; /* how many data lines follows */
unsigned int number_of_columns;

string cur_ifilename; /* input */
string cur_ofilename; /* output */
string output_data_type; /* part of output-filename */

cout << "\nDeleting old data files...\n\n";

#ifdef _WIN32
system("del /Q *.tex");
#else
system("rm -f *.tex");
#endif


/*******************************************************
* scan the first input file for possible data types *
*******************************************************/

set_file_names(0, cur_ifilename, cur_ofilename, output_data_type);

ifstream infile( cur_ifilename.c_str() );

if( not infile )
{
cout << "\n\nERROR!\n**********\nCouln't open file " << cur_ifilename
<< endl;
return 1;
}

linenumber = 0; /* debug */
while( getline( infile, read_line) )
{

linenumber++; /* update */

if( linenumber == 2)
{
istringstream input( read_line.substr( 0, read_line.find('
') ) );
input >> number_of_columns;
}
else if( read_line.find("SCALARS") != string::npos )
{
/* "SCALARS" was found in read_line */
possible_data_types.push_back(read_line);
}
else if( read_line.find("CELL_DATA") != string::npos )
{
istringstream input( read_line.substr( read_line.find(' ')+1 ) );
input >> number_of_lines;
}
}
infile.close();


/*********************************************
* ask which data type should be converted *
********************************************/

cout << "*******************************************" << endl;
cout << "From initial data file: number_of_lines = " << number_of_lines <<
endl << endl;
data_type = 0;
for( vector<string>::const_iterator it = possible_data_types.begin();
it != possible_data_types.end(); ++it)
{
data_type++;
cout << data_type << ": " << *it << endl;
}
cout << endl << "Which datatype (number) should be converted ? ";
cin >> data_type;

current_data_type = possible_data_types[data_type-1];

output_data_type =
trim( current_data_type.substr( current_data_type.find(' '),
current_data_type.rfind(' ')) );


/*******************************
* convert data in all files *
*******************************/

for(filenumber=0; filenumber<999; filenumber++)
{

set_file_names(filenumber, cur_ifilename,
cur_ofilename, output_data_type);

linenumber = 0;
ifstream infile( cur_ifilename.c_str() );

if ( infile.is_open() )
{
while( getline( infile, read_line ) )
{

linenumber++; /* counter for debugging */

if( read_line == current_data_type )
{
cout << read_line << endl; /* debug */

convert_data( linenumber, number_of_lines,
infile, cur_ofilename);
}
}
}
else
break; /* no more files to go, don't try up to 999 */

infile.close();
}


cout << endl << filenumber << " number of .TeX files written" << endl <<
endl;
return 0;

}
 
G

Guest

BobR said:
Martin Jørgensen wrote in message
<[email protected]>...
BobR wrote: -snip-



It demonstrates searching through a file ("Filer.h") for a certain text
('FindThis'). Then it 'inserts' a line into the vector (class 'Filer' is
derived from a std::vector, so, it acts like a vector.). Then it adds a line
"-- This is a copy --" to the end (using 'push_back()').

Ok, I notice that...
Then it writes the vector out to a file "CopyFiler.txt". You can open that
file in any text editor to verify that the original file and the new file are
different.

Yep, I saw that...
Does that 'splain enough?

Great, thanks... I think it does although I'll have to sit and spend
some time on it later today in the afternoon, hopefully...


Best regards
Martin Jørgensen
 
B

BobR

I like to give credit where it's due. I forgot to mention that the heart of
'Filer.h' came from Andrew Koenig who said he learned it from Walter Brown:

ifstream file("levels\\level1.txt");
for ( string line; getline( file, line ); ) {
// whatever
}

I thought it was such a slick little piece of code that I have replaced
almost all of my 'while(readfile)' loops with it.
Of course, you pick the proper tool for the job, not make the job fit the
tool. <G>
 
B

BobR

Martin Jørgensen wrote in message
<[email protected]>...
BobR wrote:
-snip-

/* """

/*****************************************************/
void convert_data(unsigned int &linenumber, const unsigned int
&number_of_lines, const ifstream &infile, const string
&cur_ofilename){
double read_value;
string LaTeX_header = "\\documentclass{article}\n....";
string LaTeX_tail = " \\end{tabular}}\n\n\\end{document}\n\n";
/***********************************
* do the actual conversion here *
***********************************/
ofstream outfile( cur_ofilename.c_str() ); /* open output-file */
outfile << LaTeX_header;
for(unsigned int line=1; linenumber<number_of_lines; linenumber++) {
linenumber++;

/* **************************************************
OKAY: When I come to this point the input file looks like:
---
SCALARS something double 1
543.2
342.1
123.5
643.2
....
etc.
----
I want to read the number: 543.2 into a variable, such as read_value, but I
get compiler error...

In function ‘void convert_data(unsigned int&, const unsigned int&, const
std::ifstream&, const std::string&)’:
output_to_latex.cpp:67: error: no matching function for call to
‘std::basic_ifstream<char, std::char_traits<char> >::getline(std::string&)
const’
......***********************************************
*/

""" */

??? Try removing the 'const' on the ifstream reference, and see what happens.
string read_line; // <<<<<<<<<<<-------- ERROR
infile.getline( read_line ); // <<<<<<<<<<<-------- ERROR

Keep in mind that 'getline' reads the WHOLE line up to the next delimiter
(which defaults to a newline '\n'), but does not read the newline (newline
can be one char or two chars or ? depending on OS).
infile >> read_value;

So, you could be trying to put "\n" into a type double var.

Here is a little test I put together. Maybe it will give you an idea:

// ------------------------------------
void Testisdigit( std::eek:stream &cout ){
cout<<"\n_____[ "<<__PRETTY_FUNCTION__<<" ]_____"<<std::endl;
// ----------
// #include <ccytpe> // ISO C++ 14882: <ccytpe>
cout<<"\n_______ isdigit test _______"<<std::endl;
int Inum(0);
double Dnum(0);
std::string TestForNum("Hi 4 76.5num 42.7e-5");
cout<<"Test string = "<<TestForNum<<"."<<std::endl;
for(size_t i(0); i < TestForNum.size(); ++i){
cout<<"char at "<<i<<" is "<<TestForNum.at(i)<<", a ";
if( std::isdigit( TestForNum.at(i) ) ){
std::istringstream strStream( TestForNum.substr(i) );
strStream >> Inum;
strStream.clear();
strStream.str( TestForNum.substr(i) );
strStream >> Dnum;
strStream.clear();
cout<<"digit Inum="<<Inum
<<" Dnum="<<Dnum<<std::endl;
}
else{ cout<<"alpha"<<std::endl;}
}
cout<<"_______ isdigit test _______Done"<<std::endl;
// ----------
cout<<"_____[ "<<__FUNCTION__<<" ]__End\n"<<std::endl;
return;
} // Testisdigit(ostream&)
// ------------------------------------
/* -- output --
_______ isdigit test _______
Test string = Hi 4 76.5num 42.7e-5.
char at 0 is H, a alpha
char at 1 is i, a alpha
char at 2 is , a alpha
char at 3 is 4, a digit Inum=4 Dnum=4
char at 4 is , a alpha
char at 5 is 7, a digit Inum=76 Dnum=76.5
char at 6 is 6, a digit Inum=6 Dnum=6.5
char at 7 is ., a alpha
char at 8 is 5, a digit Inum=5 Dnum=5
char at 9 is n, a alpha
char at 10 is u, a alpha
char at 11 is m, a alpha
char at 12 is , a alpha
char at 13 is 4, a digit Inum=42 Dnum=0.000427
char at 14 is 2, a digit Inum=2 Dnum=2.7e-005
char at 15 is ., a alpha
char at 16 is 7, a digit Inum=7 Dnum=7e-005
char at 17 is e, a alpha
char at 18 is -, a alpha
char at 19 is 5, a digit Inum=5 Dnum=5
_______ isdigit test _______Done
*/
Your output may be different, I don't know what I had 'precision()' set to.


/* """

/*****************************************************/
int main(){
string current_data_type;
vector<string> possible_data_types;
int data_type;
string read_line;

unsigned int filenumber; /* current data file number */
// unsigned int linenumber; /* current line */
unsigned int number_of_lines; /* how many data lines follows */
unsigned int number_of_columns;

string cur_ifilename; /* input */
string cur_ofilename; /* output */
// string output_data_type; /* part of output-filename */
""" */

Style police here - putting all your declarations at the top of a block is
kinda 'C' like. In 'C++', we like to put them as close to usage as is
reasonable.

<snip>
/*******************************************************
* scan the first input file for possible data types *
*******************************************************/
// So, move this to here:
string output_data_type; /* part of output-filename */
// ...it's first use is in the next line.
set_file_names(0, cur_ifilename, cur_ofilename, output_data_type);
<snip>

// linenumber = 0; /* debug */
// Move this to here: (etc.)
unsigned int linenumber(0); /* current line */
while( getline( infile, read_line) ){
} // while(getline)
infile.close();
// Hey, you ARE smart! I was about to point that out to you.


Give those things some thought and come back with questions and/or let me
know if you "got 'er done".

BTW, 'unsigned int' is usually typedefed to 'size_t', so you could use that
(may need 'std::size_t' on newest implementations). I find it easier to type,
but it's your choice.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top