By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,236 Members | 2,051 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,236 IT Pros & Developers. It's quick & easy.

first program evaluation

P: n/a
Hi,

I just made my first c++ program, and I would like to know if there are
things I can do better. Also, the exe is about 500 kb, can I make it
smaller?

Thanks!
Pieter


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

int main()
{
string buffer;
string includebuffer;
string bestand;
string configin;
string configout;

ifstream config("config.txt");
getline(config, configin);
getline(config, configout);
config.close();

ifstream infile(configin.c_str());
ofstream outfile(configout.c_str());

while (getline(infile, buffer))
{
if (buffer == "")
{
outfile << " " << endl;
}
else
{
if (buffer.substr(1,7) == "include")
{
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
ifstream includefile(bestand.c_str());
while (getline(includefile, includebuffer))
{
outfile << includebuffer << endl;
}
includefile.close();
}
else
{
outfile << buffer << endl;
}
}
}

infile.close();
outfile.close();
return 0;
}

Jul 22 '05 #1
Share this Question
Share on Google+
30 Replies


P: n/a
Pieter Provoost wrote:
I just made my first c++ program, and I would like to know if there are
things I can do better.
Write unit tests for every function.
Also, the exe is about 500 kb, can I make it
smaller?
That is a FAQ for this newsgroup. The good news is as your program gets
larger the executable size will not grow proportionally. You can add a lot
of code before you hit 501 kb. The executable is big because many features
you did not use got linked in.
#include <string>
#include <fstream>
using namespace std;
Don't use 'using namespace'. Invite only the identifiers you need in, such
as using std::string. As a program gets huge, many 'using namespace'
statements will cause major problems, including bugs in your compiler, and
name collisions.
int main()
{
string buffer;
string includebuffer;
string bestand;
string configin;
string configout;
Put each of these as close as possible to the code that uses them.
ifstream config("config.txt");
getline(config, configin);
getline(config, configout);
config.close();
Cut these up into functions. But...
ifstream infile(configin.c_str());
ofstream outfile(configout.c_str());
....these could have been command line arguments. Research argv and argc.
while (getline(infile, buffer))
Nice. Some folks at this point use either infile >> string, or scanf. Both
are user hostile.
{
if (buffer == "")
{
outfile << " " << endl;
Why the little space?
}
else
{
if (buffer.substr(1,7) == "include")
{
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
That line does too much. Pull out the first find_first_of, and put its
result in a variable, and give that variable a name.
bestand += ".tex";
ifstream includefile(bestand.c_str());
while (getline(includefile, includebuffer))
{
outfile << includebuffer << endl;
}
includefile.close();
}
else
{
outfile << buffer << endl;
If you did not have the if(buffer == "") up there, then control flow would
drop to here, and do the same thing.
}
}
}

infile.close();
outfile.close();
return 0;
}


Good luck!

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #2

P: n/a

"Phlip" <ph*******@yahoo.com> schreef in bericht
news:vw*****************@newssvr16.news.prodigy.co m...
Pieter Provoost wrote:
I just made my first c++ program, and I would like to know if there are
things I can do better.


Write unit tests for every function.
Also, the exe is about 500 kb, can I make it
smaller?


That is a FAQ for this newsgroup. The good news is as your program gets
larger the executable size will not grow proportionally. You can add a lot
of code before you hit 501 kb. The executable is big because many features
you did not use got linked in.
#include <string>
#include <fstream>
using namespace std;


Don't use 'using namespace'. Invite only the identifiers you need in, such
as using std::string. As a program gets huge, many 'using namespace'
statements will cause major problems, including bugs in your compiler, and
name collisions.


Ok, I'll have to look that up (don't know how to use it).

int main()
{
string buffer;
string includebuffer;
string bestand;
string configin;
string configout;


Put each of these as close as possible to the code that uses them.
ifstream config("config.txt");
getline(config, configin);
getline(config, configout);
config.close();


Cut these up into functions. But...
ifstream infile(configin.c_str());
ofstream outfile(configout.c_str());


...these could have been command line arguments. Research argv and argc.


They were command line arguments at first, but I prefer to work with the
config file and jut click the icon. I stopped using the dos command prompt
since they introduced directories with names such as "documents and
settings"...

while (getline(infile, buffer))


Nice. Some folks at this point use either infile >> string, or scanf. Both
are user hostile.
{
if (buffer == "")
{
outfile << " " << endl;


Why the little space?


Well, when I didn't have this line, I used to get an error when the program
tried to process a blank line. Maybe it's because I can't apply substring to
an empty string?

}
else
{
if (buffer.substr(1,7) == "include")
{
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));


That line does too much. Pull out the first find_first_of, and put its
result in a variable, and give that variable a name.
bestand += ".tex";
ifstream includefile(bestand.c_str());
while (getline(includefile, includebuffer))
{
outfile << includebuffer << endl;
}
includefile.close();
}
else
{
outfile << buffer << endl;


If you did not have the if(buffer == "") up there, then control flow would
drop to here, and do the same thing.


See my comments above.

}
}
}

infile.close();
outfile.close();
return 0;
}


Good luck!

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces

Thank you very much!
Pieter
Jul 22 '05 #3

P: n/a

"Pieter Provoost" <pi************@tiscali.be> schreef in bericht
news:40**********************@news.skynet.be...

"Phlip" <ph*******@yahoo.com> schreef in bericht
news:vw*****************@newssvr16.news.prodigy.co m...
Pieter Provoost wrote:
#include <string>
#include <fstream>
using namespace std;


Don't use 'using namespace'. Invite only the identifiers you need in, such as using std::string. As a program gets huge, many 'using namespace'
statements will cause major problems, including bugs in your compiler, and name collisions.


Ok, I'll have to look that up (don't know how to use it).


Found it. This does the job:

using std::string;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::getline;
Jul 22 '05 #4

P: n/a
In comp.lang.c++
"Phlip" <ph*******@yahoo.com> wrote:
Pieter Provoost wrote:
I just made my first c++ program, and I would like to know if there are
things I can do better.


Write unit tests for every function.


Opinion
#include <string>
#include <fstream>
using namespace std;


Don't use 'using namespace'. Invite only the identifiers you need in, such
as using std::string. As a program gets huge, many 'using namespace'
statements will cause major problems, including bugs in your compiler, and
name collisions.


Opinion
int main()
{
string buffer;
string includebuffer;
string bestand;
string configin;
string configout;


Put each of these as close as possible to the code that uses them.


Opinion
ifstream config("config.txt");
getline(config, configin);
getline(config, configout);
config.close();


Cut these up into functions. But...


Opinion
ifstream infile(configin.c_str());
ofstream outfile(configout.c_str());


...these could have been command line arguments. Research argv and argc.


Opinion
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));


That line does too much. Pull out the first find_first_of, and put its
result in a variable, and give that variable a name.


Opinion
Jul 22 '05 #5

P: n/a
"Pieter Provoost" <pi************@tiscali.be> wrote in news:40bb82ac$0
$2*************@news.skynet.be:
Found it. This does the job:

using std::string;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::getline;


I think you will find it to be tedious having to add a "using" statement
everytime you decide to use something from the standard library. I find it
much easier to attach "std::" in front of standard library types whenever I
use them.

std::cout << "Hope this helps" << std::endl;

Gregg
Jul 22 '05 #6

P: n/a
Bruce wrote:
Phlip wrote:
Write unit tests for every function.


Opinion


How much time do you spend, per project, operating a debugger and hunting
for weird bugs?

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #7

P: n/a
Pieter Provoost wrote:
I just made my first c++ program,
and I would like to know if there are things I can do better.
Also, the exe is about 500 kb, can I make it smaller? cat main.cc #include <string>
#include <cstdlib>
#include <fstream>
#include <iostream>

int main(int argc, char* argv[]) {
using namespace std;
int result = EXIT_SUCCESS;

ifstream config("config.txt");
if (config) {
string configin;
if (getline(config, configin)) {
ifstream infile(configin.c_str());
if (infile) {
string configout;
if (getline(config, configout)) {
ofstream outfile(configout.c_str());
if (outfile) {
string buffer;
string includebuffer;
while (getline(infile, buffer)) {
if (buffer == "") {
outfile << " " << endl;
}
else { // (buffer != "")
if (buffer.substr(1,7) == "include") {
string bestand = buffer.substr(
9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
ifstream includefile(bestand.c_str());
if (includefile) {
while (getline(includefile, includebuffer)) {
outfile << includebuffer << endl;
}
includefile.close();
}
else {// (!includefile)
cerr << "Couldn't open include file: "
<< bestand << endl;
result = EXIT_FAILURE;
break;
}
}
else { // (buffer.substr(1,7) != "include")
outfile << buffer << endl;
}
}
}
outfile.close();
}
else { // (!outfile)
cerr << "Couldn't open output file: "
<< configout << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configout))
cerr << "Couldn't read output file name!" << endl;
result = EXIT_FAILURE;
}
infile.close();
}
else { // (!infile))
cerr << "Couldn't open input file: "
<< configin << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configin))
cerr << "Couldn't read input file name!" << endl;
result = EXIT_FAILURE;
}
config.close();
}
else { // (!config)
cerr << "Couldn't open file: config.txt" << endl;
result = EXIT_FAILURE;
}
return result;
}
g++ -Wall -ansi -pedantic -o main main.cc
ls -l main

-rwxr-xr-x 1 edwin jpl 12188 May 31 13:48 main
Jul 22 '05 #8

P: n/a
"Pieter Provoost" <pi************@tiscali.be> wrote:
I just made my first c++ program, and I would like to know if there are
things I can do better. Also, the exe is about 500 kb, can I make it
smaller?
Is there a particular reason you are worried about the size of the exe?

I want to try the Socratic method on you:
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
ifstream includefile(bestand.c_str());
while (getline(includefile, includebuffer))
{
outfile << includebuffer << endl;
}
includefile.close();


What is the code above supposed to do? Use standard English to describe
it...
Jul 22 '05 #9

P: n/a
On Mon, 31 May 2004 13:50:19 -0700 in comp.lang.c++, "E. Robert Tisdale"
<E.**************@jpl.nasa.gov> wrote,
else { // (!outfile)
cerr << "Couldn't open output file: "
<< configout << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configout))
cerr << "Couldn't read output file name!" << endl;
result = EXIT_FAILURE;
}
infile.close();
}
else { // (!infile))
cerr << "Couldn't open input file: "
<< configin << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configin))
cerr << "Couldn't read input file name!" << endl;
result = EXIT_FAILURE;
}
config.close();
}
else { // (!config)
cerr << "Couldn't open file: config.txt" << endl;
result = EXIT_FAILURE;
}


This is *very* bad advice.

Jul 22 '05 #10

P: n/a

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news6.west.e arthlink.net...
"Pieter Provoost" <pi************@tiscali.be> wrote:
I just made my first c++ program, and I would like to know if there are
things I can do better. Also, the exe is about 500 kb, can I make it
smaller?


Is there a particular reason you are worried about the size of the exe?

I want to try the Socratic method on you:
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
ifstream includefile(bestand.c_str());
while (getline(includefile, includebuffer))
{
outfile << includebuffer << endl;
}
includefile.close();


What is the code above supposed to do? Use standard English to describe
it...


It's supposed to replace the line "\include{somefile.tex}" in a LaTeX file
by the contents of somefile.tex. This way I have the complete source of my
document in one file.

Jul 22 '05 #11

P: n/a

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news6.west.e arthlink.net...
"Pieter Provoost" <pi************@tiscali.be> wrote:
I just made my first c++ program, and I would like to know if there are
things I can do better. Also, the exe is about 500 kb, can I make it
smaller?


Is there a particular reason you are worried about the size of the exe?

I want to try the Socratic method on you:
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
ifstream includefile(bestand.c_str());
while (getline(includefile, includebuffer))
{
outfile << includebuffer << endl;
}
includefile.close();


What is the code above supposed to do? Use standard English to describe
it...


About the file size: no there's no particular reasin, but I just supposed it
would be a lot smaller since it's quite simple.
Jul 22 '05 #12

P: n/a
Pieter Provoost wrote:

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news6.west.e arthlink.net...
"Pieter Provoost" <pi************@tiscali.be> wrote:
I just made my first c++ program, and I would like to know if there are
things I can do better. Also, the exe is about 500 kb, can I make it
smaller?


Is there a particular reason you are worried about the size of the exe?

I want to try the Socratic method on you:
bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
ifstream includefile(bestand.c_str());
while (getline(includefile, includebuffer))
{
outfile << includebuffer << endl;
}
includefile.close();


What is the code above supposed to do? Use standard English to describe
it...


About the file size: no there's no particular reasin, but I just supposed it
would be a lot smaller since it's quite simple.


Don't know if somebody already asked this:
Are you sure you have turned on compiler optimization and
are not building a 'debug' version?

Debug versions usually are much larger then release version,
since a lot of symbol table information is packed into the
executable among other things.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #13

P: n/a

"Karl Heinz Buchegger" <kb******@gascad.at> schreef in bericht
news:40***************@gascad.at...
Pieter Provoost wrote:

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news6.west.e arthlink.net...
"Pieter Provoost" <pi************@tiscali.be> wrote:

>I just made my first c++ program, and I would like to know if there are >things I can do better. Also, the exe is about 500 kb, can I make it
>smaller?

Is there a particular reason you are worried about the size of the exe?
I want to try the Socratic method on you:

> bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
> bestand += ".tex";
> ifstream includefile(bestand.c_str());
> while (getline(includefile, includebuffer))
> {
> outfile << includebuffer << endl;
> }
> includefile.close();

What is the code above supposed to do? Use standard English to describe it...


About the file size: no there's no particular reasin, but I just supposed it would be a lot smaller since it's quite simple.


Don't know if somebody already asked this:
Are you sure you have turned on compiler optimization and
are not building a 'debug' version?

Debug versions usually are much larger then release version,
since a lot of symbol table information is packed into the
executable among other things.

--
Karl Heinz Buchegger
kb******@gascad.at

Ah I probably made a debug version. I used msdev and the exe ended up in a
directory called "debug". I didn't know optimization is possible, I'll check
it out right away.

Thanks!
Jul 22 '05 #14

P: n/a
Don't know if somebody already asked this:
Are you sure you have turned on compiler optimization and
are not building a 'debug' version?

Debug versions usually are much larger then release version,
since a lot of symbol table information is packed into the
executable among other things.

--
Karl Heinz Buchegger
kb******@gascad.at

Ah I probably made a debug version. I used msdev and the exe ended up in a
directory called "debug". I didn't know optimization is possible, I'll

check it out right away.

Thanks!


Can anybody help me here? I can't find it in VC++.
Jul 22 '05 #15

P: n/a

"David Harmon" <so****@netcom.com.invalid> wrote in message
news:41****************@news.west.earthlink.net...
On Mon, 31 May 2004 13:50:19 -0700 in comp.lang.c++, "E. Robert Tisdale"
<E.**************@jpl.nasa.gov> wrote,
else { // (!outfile)
cerr << "Couldn't open output file: "
<< configout << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configout))
cerr << "Couldn't read output file name!" << endl;
result = EXIT_FAILURE;
}
infile.close();
}
else { // (!infile))
cerr << "Couldn't open input file: "
<< configin << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configin))
cerr << "Couldn't read input file name!" << endl;
result = EXIT_FAILURE;
}
config.close();
}
else { // (!config)
cerr << "Couldn't open file: config.txt" << endl;
result = EXIT_FAILURE;
}


This is *very* bad advice.


Care to elaborate? What's the "very bad" part? Using such deep nesting?
Using cerr? Using failure result codes? Or...?

For maximum protection, I'd utilize RAII for handling resources (and the
success or failure of obtaining them). But given the simpicity of the
original post, I'd suggest that might simply confuse the user with a lot of
overhead. They can get into RAII later.

But I'm curious as to exactly what you've found in his response that was
"very bad"...? (Given a cursory glance, it looks like somewhat typical
open/close nesting code.)

-Howard



Jul 22 '05 #16

P: n/a

"Howard" <al*****@hotmail.com> schreef in bericht
news:tx********************@bgtnsc05-news.ops.worldnet.att.net...

"David Harmon" <so****@netcom.com.invalid> wrote in message
news:41****************@news.west.earthlink.net...
On Mon, 31 May 2004 13:50:19 -0700 in comp.lang.c++, "E. Robert Tisdale"
<E.**************@jpl.nasa.gov> wrote,
else { // (!outfile)
cerr << "Couldn't open output file: "
<< configout << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configout))
cerr << "Couldn't read output file name!" << endl;
result = EXIT_FAILURE;
}
infile.close();
}
else { // (!infile))
cerr << "Couldn't open input file: "
<< configin << endl;
result = EXIT_FAILURE;
}
}
else { // (!getline(config, configin))
cerr << "Couldn't read input file name!" << endl;
result = EXIT_FAILURE;
}
config.close();
}
else { // (!config)
cerr << "Couldn't open file: config.txt" << endl;
result = EXIT_FAILURE;
}
This is *very* bad advice.


Care to elaborate? What's the "very bad" part? Using such deep nesting?
Using cerr? Using failure result codes? Or...?

For maximum protection, I'd utilize RAII for handling resources (and the
success or failure of obtaining them). But given the simpicity of the
original post, I'd suggest that might simply confuse the user with a lot

of overhead. They can get into RAII later.

Exactly!
But I'm curious as to exactly what you've found in his response that was
"very bad"...? (Given a cursory glance, it looks like somewhat typical
open/close nesting code.)

-Howard

Jul 22 '05 #17

P: n/a
Pieter Provoost wrote:
Don't know if somebody already asked this:
Are you sure you have turned on compiler optimization and
are not building a 'debug' version?

Debug versions usually are much larger then release version,
since a lot of symbol table information is packed into the
executable among other things.

--
Karl Heinz Buchegger
kb******@gascad.at

Ah I probably made a debug version. I used msdev and the exe ended up in a
directory called "debug". I didn't know optimization is possible, I'll

check
it out right away.

Thanks!


Can anybody help me here? I can't find it in VC++.


First of all: This isn't really a question on C++ but on the
tool you use. Thus it should be asked in a hewsgroup dedictaed
to VC++. Look at Shivas Welcome message, it contains some suggestions
of where to ask. http://www.slack.net/~shiva/welcome.txt

Anyway: 2 Methods

1. You can select the 'active configuration' with
Menu: 'Build' 'Set active configuration'

2. Start VC++, Right click in the toolbar section (anywhere in empty space).
Select 'Customize'. A dialog opens, make sure you have the 'Commands' tab
selected. Select the 'Build' category. In the right part of the dialog some
buttons and a combo box appear. Klick that combo box and drag it into a
toolbar. Click 'Close'

In this combo box, the 'active configuration' (Debug - Release) will be shown and
can be changed.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #18

P: n/a
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news6.west. earthlink.net...
"Pieter Provoost" <pi************@tiscali.be> wrote:
>I just made my first c++ program, and I would like to know if there are
>things I can do better. Also, the exe is about 500 kb, can I make it
>smaller?


Is there a particular reason you are worried about the size of the exe?

I want to try the Socratic method on you:
> bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
> bestand += ".tex";
> ifstream includefile(bestand.c_str());
> while (getline(includefile, includebuffer))
> {
> outfile << includebuffer << endl;
> }
> includefile.close();


What is the code above supposed to do? Use standard English to describe
it...


It's supposed to replace the line "\include{somefile.tex}" in a LaTeX file
by the contents of somefile.tex. This way I have the complete source of my
document in one file.


OK then, lets turn that into a function:

void insertFile( ostream& os, const string& fileName )
{
ifstream includefile( fileName );
string includebuffer;
while ( getline( includefile, includebuffer ) )
os << includebuffer << endl;
}

In main we have:

string bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
insertFile( outfile, bestand );

and we can remove the line:

string bestand;

From the top of the file.

What do you think of this minor change? Does it make main easer to
understand or harder? Is the function created easy to understand? Do you
think you could use the insertFile function in other contexts?
Jul 22 '05 #19

P: n/a

"Karl Heinz Buchegger" <kb******@gascad.at> schreef in bericht
news:40***************@gascad.at...
Pieter Provoost wrote:
> Don't know if somebody already asked this:
> Are you sure you have turned on compiler optimization and
> are not building a 'debug' version?
>
> Debug versions usually are much larger then release version,
> since a lot of symbol table information is packed into the
> executable among other things.
>
> --
> Karl Heinz Buchegger
> kb******@gascad.at
Ah I probably made a debug version. I used msdev and the exe ended up in a directory called "debug". I didn't know optimization is possible, I'll check
it out right away.

Thanks!


Can anybody help me here? I can't find it in VC++.


First of all: This isn't really a question on C++ but on the
tool you use. Thus it should be asked in a hewsgroup dedictaed
to VC++. Look at Shivas Welcome message, it contains some suggestions
of where to ask. http://www.slack.net/~shiva/welcome.txt

Anyway: 2 Methods

1. You can select the 'active configuration' with
Menu: 'Build' 'Set active configuration'

2. Start VC++, Right click in the toolbar section (anywhere in empty

space). Select 'Customize'. A dialog opens, make sure you have the 'Commands' tab selected. Select the 'Build' category. In the right part of the dialog some buttons and a combo box appear. Klick that combo box and drag it into a
toolbar. Click 'Close'

In this combo box, the 'active configuration' (Debug - Release) will be shown and can be changed.

--
Karl Heinz Buchegger
kb******@gascad.at


Thanks! It's about 140 kb now instead of 500.
Jul 22 '05 #20

P: n/a
Pieter Provoost wrote:


Thanks! It's about 140 kb now instead of 500.


Changing the project properties to use a shared
runtime library brings it down to 16 kByte. But then
you need to provide the required DLL's with your exe.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #21

P: n/a

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news1.west.e arthlink.net...
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news6.west. earthlink.net...
"Pieter Provoost" <pi************@tiscali.be> wrote:

>I just made my first c++ program, and I would like to know if there are >things I can do better. Also, the exe is about 500 kb, can I make it
>smaller?

Is there a particular reason you are worried about the size of the exe?

I want to try the Socratic method on you:

> bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
> bestand += ".tex";
> ifstream includefile(bestand.c_str());
> while (getline(includefile, includebuffer))
> {
> outfile << includebuffer << endl;
> }
> includefile.close();

What is the code above supposed to do? Use standard English to describe
it...


It's supposed to replace the line "\include{somefile.tex}" in a LaTeX fileby the contents of somefile.tex. This way I have the complete source of mydocument in one file.


OK then, lets turn that into a function:

void insertFile( ostream& os, const string& fileName )
{
ifstream includefile( fileName );
string includebuffer;
while ( getline( includefile, includebuffer ) )
os << includebuffer << endl;
}

In main we have:

string bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
insertFile( outfile, bestand );

and we can remove the line:

string bestand;

From the top of the file.

What do you think of this minor change? Does it make main easer to
understand or harder? Is the function created easy to understand? Do you
think you could use the insertFile function in other contexts?


Yes I definately think it's a good change. There's one thing that I don't
understand: why is there a "&" after ostream and string?

Thank you!
Jul 22 '05 #22

P: n/a
Pieter Provoost wrote:

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news1.west.e arthlink.net...
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news6.west. earthlink.net...
> "Pieter Provoost" <pi************@tiscali.be> wrote:
>
> >I just made my first c++ program, and I would like to know if there are> >things I can do better. Also, the exe is about 500 kb, can I make it
> >smaller?
>
> Is there a particular reason you are worried about the size of the exe?
>
> I want to try the Socratic method on you:
>
> > bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
> > bestand += ".tex";
> > ifstream includefile(bestand.c_str());
> > while (getline(includefile, includebuffer))
> > {
> > outfile << includebuffer << endl;
> > }
> > includefile.close();
>
> What is the code above supposed to do? Use standard English to describe
> it...

It's supposed to replace the line "\include{somefile.tex}" in a LaTeX fileby the contents of somefile.tex. This way I have the complete source of mydocument in one file.


OK then, lets turn that into a function:

void insertFile( ostream& os, const string& fileName )
{
ifstream includefile( fileName );
string includebuffer;
while ( getline( includefile, includebuffer ) )
os << includebuffer << endl;
}

In main we have:

string bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
insertFile( outfile, bestand );

and we can remove the line:

string bestand;

From the top of the file.

What do you think of this minor change? Does it make main easer to
understand or harder? Is the function created easy to understand? Do you
think you could use the insertFile function in other contexts?


Yes I definately think it's a good change. There's one thing that I don't
understand: why is there a "&" after ostream and string?


In this case '&' means: reference.
Instead of creating a copy of the original object during the call, a reference
to these objects is passed to the function and thus avoiding to
duplicate the objects (which BTW would be impossible with a stream object)

Look up references in your C++ book. You will use them often in
the future if continue programmin in C++.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #23

P: n/a
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
What do you think of this minor change? Does it make main easer to
understand or harder? Is the function created easy to understand? Do you
think you could use the insertFile function in other contexts?


Yes I definately think it's a good change.


You may be wondering at this point, why I picked that particular block
of code to extract into a seperate function. First, I noticed that there
were two variables that were only being used in that particular block of
code and not being used anywhere else in the program (includefile, and
includebuffer.) Second, when I asked you what that block of code did,
you were able to explain it with a simple phrase, one that translated
well into a function name.

Do you see any blocks of code where one or two variables are only being
used in that block and nowhere else? What would you say each block of
code is doing? Care to try turning one of them into a function?
In the mean time, let me introduce you to the 'else if' statement. It
will help make the main body of your code easier to read. Like this:

if (buffer == "")
{
outfile << " " << endl;
}
else if (buffer.substr(1,7) == "include")
{
string bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
insertFile( outfile, bestand );
}
else
{
outfile << buffer << endl;
}

See how this removes some of the odd nesting you had, without changing
the meaning of the code?
Jul 22 '05 #24

P: n/a

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news5.west.e arthlink.net...
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
What do you think of this minor change? Does it make main easer to
understand or harder? Is the function created easy to understand? Do you think you could use the insertFile function in other contexts?


Yes I definately think it's a good change.


You may be wondering at this point, why I picked that particular block
of code to extract into a seperate function. First, I noticed that there
were two variables that were only being used in that particular block of
code and not being used anywhere else in the program (includefile, and
includebuffer.) Second, when I asked you what that block of code did,
you were able to explain it with a simple phrase, one that translated
well into a function name.

Do you see any blocks of code where one or two variables are only being
used in that block and nowhere else? What would you say each block of
code is doing? Care to try turning one of them into a function?
In the mean time, let me introduce you to the 'else if' statement. It
will help make the main body of your code easier to read. Like this:

if (buffer == "")
{
outfile << " " << endl;
}
else if (buffer.substr(1,7) == "include")
{
string bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
insertFile( outfile, bestand );
}
else
{
outfile << buffer << endl;
}

See how this removes some of the odd nesting you had, without changing
the meaning of the code?

Ok, I made a new function (called bestand) that constructs the filename from
the line that contains "include". Maybe I should make a function that reads
all the lines of the configfile to an array? If I choose to add more
configuration parameters to the program later, I won't have to change that
part... Another question: do I really need the "const" before "string&"?

Thank you very much!


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

void insertfile(ostream& os, const string& filename)
{
ifstream includefile(filename.c_str());
string includebuffer;
while (getline(includefile, includebuffer))
os << includebuffer << endl;
}

string bestand(const string& bufferline)
{
string firstpart = bufferline.substr(9, (bufferline.find_first_of("}") -
9));
firstpart += ".tex";
return firstpart;
}

int main()
{
string buffer;
string configin;
string configout;

ifstream config("config.txt");
getline(config, configin);
getline(config, configout);
config.close();

ifstream infile(configin.c_str());
ofstream outfile(configout.c_str());

while (getline(infile, buffer))
{
if (buffer == "")
{
outfile << " " << endl;
}
else if (buffer.substr(1,7) == "include")
{
insertfile(outfile, bestand(buffer));
}
else
{
outfile << buffer << endl;
}
}
infile.close();
outfile.close();
return 0;
}

Jul 22 '05 #25

P: n/a
> Maybe I should make a function that reads
all the lines of the configfile to an array? If I choose to add more
configuration parameters to the program later, I won't have to change that
part...


This probably is a stupid question, but can I something like this?

string filetoarray[]("textfile.txt")
{
string arraywithlines[];
// some code
return arraywithlines[];
}
Jul 22 '05 #26

P: n/a
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news5.west. earthlink.net...
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
>> What do you think of this minor change? Does it make main easer to
>> understand or harder? Is the function created easy to understand? Doyou >> think you could use the insertFile function in other contexts?
>
>Yes I definately think it's a good change.
You may be wondering at this point, why I picked that particular block
of code to extract into a seperate function. First, I noticed that there
were two variables that were only being used in that particular block of
code and not being used anywhere else in the program (includefile, and
includebuffer.) Second, when I asked you what that block of code did,
you were able to explain it with a simple phrase, one that translated
well into a function name.

Do you see any blocks of code where one or two variables are only being
used in that block and nowhere else? What would you say each block of
code is doing? Care to try turning one of them into a function?
In the mean time, let me introduce you to the 'else if' statement. It
will help make the main body of your code easier to read. Like this:

if (buffer == "")
{
outfile << " " << endl;
}
else if (buffer.substr(1,7) == "include")
{
string bestand = buffer.substr(9, (buffer.find_first_of("}") - 9));
bestand += ".tex";
insertFile( outfile, bestand );
}
else
{
outfile << buffer << endl;
}

See how this removes some of the odd nesting you had, without changing
the meaning of the code?

Ok, I made a new function (called bestand) that constructs the filename from
the line that contains "include". Maybe I should make a function that reads
all the lines of the configfile to an array? If I choose to add more
configuration parameters to the program later, I won't have to change that
part... Another question: do I really need the "const" before "string&"?


I suggest either "const string&" or "string". Just putting "string&"
should only be used if you want the function to modify the argument
passed in instead of (or as well as) returning information.

string bestand(const string& bufferline)
{
string firstpart = bufferline.substr(9, (bufferline.find_first_of("}") -
9));
firstpart += ".tex";
return firstpart;
}
What does "bestand" mean? Maybe we can come up with a better name here?
Can you think of other contexts where this function would be useful?
ifstream config("config.txt");
getline(config, configin);
getline(config, configout);
config.close();
What does the above block of code do?

ifstream infile(configin.c_str());
ofstream outfile(configout.c_str());

while (getline(infile, buffer))
{
if (buffer == "")
{
outfile << " " << endl;
}
else if (buffer.substr(1,7) == "include")
{
insertfile(outfile, bestand(buffer));
}
else
{
outfile << buffer << endl;
}
}


Tell me if this statement describes the above block of code. "copy
infile to outfile until a "include" line is reached, insert the named
file at that point in the outfile, then continue copying as above." If
it does, can you think of another algorithm to do it?
Jul 22 '05 #27

P: n/a

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news4.west.e arthlink.net...
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news5.west. earthlink.net...
In article <c9**********@gaudi2.UGent.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:

>> What do you think of this minor change? Does it make main easer to
>> understand or harder? Is the function created easy to understand? Doyou
>> think you could use the insertFile function in other contexts?
>
>Yes I definately think it's a good change.

You may be wondering at this point, why I picked that particular block
of code to extract into a seperate function. First, I noticed that there were two variables that were only being used in that particular block of code and not being used anywhere else in the program (includefile, and
includebuffer.) Second, when I asked you what that block of code did,
you were able to explain it with a simple phrase, one that translated
well into a function name.

Do you see any blocks of code where one or two variables are only being
used in that block and nowhere else? What would you say each block of
code is doing? Care to try turning one of them into a function?
In the mean time, let me introduce you to the 'else if' statement. It
will help make the main body of your code easier to read. Like this:

if (buffer == "")
{
outfile << " " << endl;
}
else if (buffer.substr(1,7) == "include")
{
string bestand = buffer.substr(9, (buffer.find_first_of("}") - 9)); bestand += ".tex";
insertFile( outfile, bestand );
}
else
{
outfile << buffer << endl;
}

See how this removes some of the odd nesting you had, without changing
the meaning of the code?

Ok, I made a new function (called bestand) that constructs the filename fromthe line that contains "include". Maybe I should make a function that readsall the lines of the configfile to an array? If I choose to add more
configuration parameters to the program later, I won't have to change thatpart... Another question: do I really need the "const" before "string&"?


I suggest either "const string&" or "string". Just putting "string&"
should only be used if you want the function to modify the argument
passed in instead of (or as well as) returning information.

string bestand(const string& bufferline)
{
string firstpart = bufferline.substr(9, (bufferline.find_first_of("}") -
9));
firstpart += ".tex";
return firstpart;
}


What does "bestand" mean? Maybe we can come up with a better name here?
Can you think of other contexts where this function would be useful?


"bestand" means file (in dutch). Well, to be honest, I can't think of other
context where I can use this function. So I guess its better to leave it in
main() after all. Do you agree on that?

ifstream config("config.txt");
getline(config, configin);
getline(config, configout);
config.close();


What does the above block of code do?


It reads the two first lines of config.txt to variables. They could have
been command line arguments but I prefer not to use the command line here.
Do you think it's useful to make a function that reads all the lines of the
configfile to an array? That's something I can definately use in other
contexts. Something like this maybe?

string filetoarray[]("textfile.txt")
{
string arraywithlines[];
// some code
return arraywithlines[];
}

ifstream infile(configin.c_str());
ofstream outfile(configout.c_str());

while (getline(infile, buffer))
{
if (buffer == "")
{
outfile << " " << endl;
}
else if (buffer.substr(1,7) == "include")
{
insertfile(outfile, bestand(buffer));
}
else
{
outfile << buffer << endl;
}
}


Tell me if this statement describes the above block of code. "copy
infile to outfile until a "include" line is reached, insert the named
file at that point in the outfile, then continue copying as above." If
it does, can you think of another algorithm to do it?


Your description is correct, and I think this algorithm is the most
efficient way to do it.

Thank you!
Jul 22 '05 #28

P: n/a
>> >string bestand(const string& bufferline)
>{
> string firstpart = bufferline.substr(9, (bufferline.find_first_of("}") -
>9));
> firstpart += ".tex";
> return firstpart;
>}


What does "bestand" mean? Maybe we can come up with a better name here?
Can you think of other contexts where this function would be useful?


"bestand" means file (in dutch). Well, to be honest, I can't think of other
context where I can use this function. So I guess its better to leave it in
main() after all. Do you agree on that?


Personally, I would leave it in. Pulling it out doesn't make main any
simpler, and as you say it doesn't seem very reusable. However, I
wouldn't have a problem with it being a seperate function as long as we
can come up with a better name for it than simply "file" (in any
language.)

> ifstream config("config.txt");
> getline(config, configin);
> getline(config, configout);
> config.close();


What does the above block of code do?


It reads the two first lines of config.txt to variables. They could have
been command line arguments but I prefer not to use the command line here.
Do you think it's useful to make a function that reads all the lines of the
configfile to an array? That's something I can definately use in other
contexts. Something like this maybe?

string filetoarray[]("textfile.txt")
{
string arraywithlines[];
// some code
return arraywithlines[];
}


To do that, I would write something more like:

void getConfigInfo( vector<string>& data, const string& fileName ) {
// fill data with info from the file
}

and call it like this:

vector<string> configData;
getConfigInfo( configData, "config.txt" );

> ifstream infile(configin.c_str());
> ofstream outfile(configout.c_str());
>
> while (getline(infile, buffer))
> {
> if (buffer == "")
> {
> outfile << " " << endl;
> }
> else if (buffer.substr(1,7) == "include")
> {
> insertfile(outfile, bestand(buffer));
> }
> else
> {
> outfile << buffer << endl;
> }
> }


Tell me if this statement describes the above block of code. "copy
infile to outfile until a "include" line is reached, insert the named
file at that point in the outfile, then continue copying as above." If
it does, can you think of another algorithm to do it?


Your description is correct, and I think this algorithm is the most
efficient way to do it.


What if we could translate the text description direclty into code?

while ( infile ) {
copyFileUntil( infile, outfile, "\\include{" );
string fileName = extractFileName( infile );
if ( fileName != "" )
insertFile( outfile, fileName );
}

What do you think of this as a main?
Jul 22 '05 #29

P: n/a

"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news4.west.e arthlink.net...
> ifstream infile(configin.c_str());
> ofstream outfile(configout.c_str());
>
> while (getline(infile, buffer))
> {
> if (buffer == "")
> {
> outfile << " " << endl;
> }
> else if (buffer.substr(1,7) == "include")
> {
> insertfile(outfile, bestand(buffer));
> }
> else
> {
> outfile << buffer << endl;
> }
> }

Tell me if this statement describes the above block of code. "copy
infile to outfile until a "include" line is reached, insert the named
file at that point in the outfile, then continue copying as above." If
it does, can you think of another algorithm to do it?


Your description is correct, and I think this algorithm is the most
efficient way to do it.


What if we could translate the text description direclty into code?

while ( infile ) {
copyFileUntil( infile, outfile, "\\include{" );
string fileName = extractFileName( infile );
if ( fileName != "" )
insertFile( outfile, fileName );
}

What do you think of this as a main?


For me as a starter it is very complicated. It's not really clear to me what
"while(infile)" does. How does "extractfilename" know where "copyfileuntil"
stopped processing the file? What exactly is passed to "extractfilename" and
what would that function look like? It's quite confusing...

Does this algorithm have any advantages over the old version?

Thank you very much!
Pieter
Jul 22 '05 #30

P: n/a
In article <40***********************@news.skynet.be>,
"Pieter Provoost" <pi************@tiscali.be> wrote:
"Daniel T." <po********@eathlink.net> schreef in bericht
news:po******************************@news4.west. earthlink.net...
>> > ifstream infile(configin.c_str());
>> > ofstream outfile(configout.c_str());
>> >
>> > while (getline(infile, buffer))
>> > {
>> > if (buffer == "")
>> > {
>> > outfile << " " << endl;
>> > }
>> > else if (buffer.substr(1,7) == "include")
>> > {
>> > insertfile(outfile, bestand(buffer));
>> > }
>> > else
>> > {
>> > outfile << buffer << endl;
>> > }
>> > }
>>
>> Tell me if this statement describes the above block of code. "copy
>> infile to outfile until a "include" line is reached, insert the named
>> file at that point in the outfile, then continue copying as above." If
>> it does, can you think of another algorithm to do it?
>
>Your description is correct, and I think this algorithm is the most
>efficient way to do it.
What if we could translate the text description direclty into code?

while ( infile ) {
copyFileUntil( infile, outfile, "\\include{" );
string fileName = extractFileName( infile );
if ( fileName != "" )
insertFile( outfile, fileName );
}

What do you think of this as a main?


For me as a starter it is very complicated. It's not really clear to me what
"while(infile)" does.


Sorry, it is shorthand for "while( !infile.fail() )" IE as long as the
next operation will succeed, keep working on the stream.

How does "extractfilename" know where "copyfileuntil"
stopped processing the file?
'extractFileName' doesn't know where copyFileUntil stopped processing,
it doesn't know anything about copyFileUntil at all. All extractFileName
knows is that it should pull the file name out of the stream. To do
this, it must know that '}' represents the end of the file name.

What exactly is passed to "extractfilename" and
what would that function look like? It's quite confusing...
Let's set up a test to demonstrate:

string extractFileName( istream& st );

void testExtractFileName() {
// first, create a stream with some data in it
// we do this because we don't want to have to make a special
// file to test with
stringstream ss;
ss << "myFile}\nrest";
// the above code also shows us what extractFileName expects
// ie what assumptions it makes about the stream. Namely that
// the name of the file is next in the stream and ends with "}\n"
string result = extractFileName( ss );
assert( result == "myFile.tex" );
// in the above, we run the function and then check the result
// we know what we want, and the assert automatically checks it.
string rest;
ss >> rest;
assert( rest == "rest" );
// the above code shows that the "}\n" was removed properly
// leaving the 'rest' of the stream intact.
}

Note, I did *not* implement extractFileName, I leave that for you to do,
but the goal is for you to be able to execute the test function and have
it return without either of the asserts firing... (You might notice that
extractFileName does much the same thing that your 'bestand' function
does.

Does this algorithm have any advantages over the old version?


Not if you find it harder to understand. However I chose the algorithm
because I felt it more directly did what it was we want to do: namely
"copy infile to outfile until a "include" line is reached, insert the
named file at that point in the outfile, then continue copying as above."

The code I wrote literally copies the infile to the outfile until an
include line is reached (that's the job of copyFileUntil,) then extracts
the named file (thats what extractFileName does,) and inserts that file
into the outfile (the job of insertFile.) Then it loops back around and
continues.
Jul 22 '05 #31

This discussion thread is closed

Replies have been disabled for this discussion.