this seems like an...Infinite Loop...

T

titan0111

Hi, it's me again.

Thank you guys for helping me with other error messages.

This is the source code.

It goes throught compiler fine but when I run it,

it seems to be in infinite loop.

Can you tell me what's causing it?




// This is a program which reads a data from a file, where each record
contains
// the amount of one snowfall. This amount will be supplied as
feet(integer),
// inches(float), and date(string, with format MM/DD). Then creates an
output file
// which lists the snowfalls from largest to smallest in table format.
At the end
// of the table, outputs the total amount of snowfall received.

#include<iostream>
#include<iomanip>
#include<cstring>
#include<fstream>
using namespace std;

class snowfall
{
private:
int ft;

float in;
float totalsfin;

char date[6];

static int validcount;
static int invalidcount;

public:
void readdata(ifstream& infile)

// reads a data from input.txt file

{
infile>> date >> ft >> in;
}

void writedata(ofstream& outfile)

// outputs a data.

{
outfile<< setw(5) << date << setw(5) << ft << " feet " << setw(3)
<< setfill(' ') << setw(5) << fixed << showpoint
<< setprecision(2) << in << " inches\n";
}

void updatevalidcount()

// validcount counter

{
++validcount;
}

void updateinvalidcount()

// invalidcount counter

{
++invalidcount;
}

void calctotalsf()

// calculates total snowfalls in inches by multiplying 12 to feet and
adding
// it to inches

{
totalsfin += float(ft)*12 + in;
}

int getft()
{return ft;}

float getin()
{return in;}

char* getdate()
{return date;}

int getvalidcount()
{return validcount;}

int getinvalidcount()
{return invalidcount;}

int operator == (char[]);

char datavalid();

void writetotalsf(ofstream& outfile);
};

int snowfall::eek:perator == (char str[])

// overloading operator == to compare two strings

{
return (strcmp(date, str) == 0) ? 1 : 0;
}

char snowfall::datavalid()

// checking to see both feet and inches are greater than 0, since they
can't
// be negative numbers.

{
char valid;

if ((ft >= 0) && (in >= 0.0f))
valid = 'T';
else
valid = 'F';
return valid;
}

void snowfall::writetotalsf(ofstream& outfile)

// converts total snowfalls in inches to feet and inches. Then outputs
them.

{
int totalsfft = 0;

if (totalsfin >= 12.0f)
while (totalsfin <= 11.0f)
{
++totalsfft;
totalsfin -= 12.0f;
}

outfile<< "/nThe total amount of snowfalls: " << totalsfft
<< " feet " << totalsfin << " inches.\n";
}

int snowfall::validcount;
int snowfall::invalidcount;

void main()
{
snowfall sf[10];
snowfall validsf[10];
snowfall invalidsf[10];

void writetitle(ofstream&);
void writeheadings(ofstream&);
void sortsf(snowfall[]);
void writevalidsf(snowfall[], ofstream&);
void writeinvalidsf(snowfall[], ofstream&);

ifstream infile;
ofstream outfile;

infile.open("c:\\downloads\\input.txt");
outfile.open("c:\\downloads\\output.txt");

if (infile && outfile)
{
int j = 0;
int k = 0;

writetitle(outfile);

// setting a loop to go 10 times since there will be maximum of 10
// records.

for (int i = 0; i <= 10; i++)
{
sf.readdata(infile);

// if dummy data, 00/00 is read, then variable i will be assigned
// 10 which will stop the loop.

if (sf.getdate() == "00/00")
i = 10;
else
{
if (sf.datavalid() == 'T')
{
validsf[j] = sf;
sf.updatevalidcount();
sf.calctotalsf();
++j;
}
else
{
invalidsf[k] = sf;
sf.updateinvalidcount();
++k;
}
}
}

sortsf(validsf);
writeheadings(outfile);
writevalidsf(validsf, outfile);
writeinvalidsf(invalidsf, outfile);
validsf.writetotalsf(outfile);
}
else
{
if (!infile)
cout<< "Unable to open file input.txt.\n";
if (!outfile)
cout<< "Unable to open file output.txt.\n";
}
}

void writetitle(ofstream& outfile)

// outputs general title informations

{
outfile<< "Title\n\n";
}

void writeheadings(ofstream& outfile)

// outputs general heading informations

{
outfile<< "Headings\n\n";
}

void sortsf(snowfall validsf[])

// sorts the list of snowfalls from largest to smallest

{
snowfall temp;

for (int i; i = validsf.getvalidcount(); i++)
for (int j; j = i + 1; j++)
if ((float(validsf.getft()) * 12 + validsf.getin()) >
(float(validsf[j].getft()) * 12 + validsf[j].getin()))
{
temp = validsf;
validsf = validsf[j];
validsf[j] = temp;
}
}

void writevalidsf(snowfall validsf[], ofstream& outfile)

// sets a loop to go whatever number in validcount variable

{
for (int i=0; i = validsf.getvalidcount(); i++)
validsf.writedata(outfile);
}

void writeinvalidsf(snowfall invalidsf[], ofstream& outfile)

// sets a loops to go whatever number in invalidcount variable, if
there is
// an invalid data, then outputs its date followed by an error message.

{
if (invalidsf[0].getinvalidcount() != 0)
for (int i = 0; i = invalidsf.getinvalidcount(); i++)
outfile<< "Invalid amount of snowfall for the date, "
<< invalidsf.getdate() << endl;
}
 
J

Jacek Dziedzic

for (int i = 0; i = invalidsf.getinvalidcount(); i++)

Are you sure you really mean to assign
'invalidsf.getinvalidcount()' to 'i' each time this
loop iterates?

HTH,
- J.
 
T

titan0111

i found what's wrong with this.

in source code i changed every = to <.
i.e. for (int i = 0; i = invalidsf.getinvalidcount(); i++) to for
(int i = 0; i < invalidsf.getinvalidcount(); i++)
 
D

Default User

i found what's wrong with this.

in source code i changed every = to <.
i.e. for (int i = 0; i = invalidsf.getinvalidcount(); i++) to for
(int i = 0; i < invalidsf.getinvalidcount(); i++)


The question is, do you know WHY that solved the problem? You should
see if you can turn up the warning level of your compiler. Many will
diagnose that problem of using = where you should have ==.




Brian
 
M

Mike Wahler

i found what's wrong with this.

in source code i changed every = to <.

But do you know *why* this fixed it? It's important that you do.
i.e. for (int i = 0; i = invalidsf.getinvalidcount(); i++) to for
(int i = 0; i < invalidsf.getinvalidcount(); i++)


An approach of blindly "change all x to y" is fraught with danger,
and does not help you really learn. E.g. sometimes the operator
in the conditional expression of a 'for' loop might be something
other than '<'. As a matter of fact, it might not contain an operator
at all. E.g.

for(int i = 0; foo(); ++i)
{
/* etc */
}

-Mike
 
R

Richard Herring

In message said:
Hi, it's me again.

Thank you guys for helping me with other error messages.

This is the source code.

It goes throught compiler fine but when I run it,

it seems to be in infinite loop.

Can you tell me what's causing it?

Just a few comments, irrelevant code snipped...
static int validcount;
static int invalidcount;

Why static? What happens if you ever have two instances of class
snowfall?
void writedata(ofstream& outfile)

// outputs a data. ....

int getft()
{return ft;}

float getin()
{return in;}

char* getdate()
{return date;}

int getvalidcount()
{return validcount;}

int getinvalidcount()
{return invalidcount;}

int operator == (char[]);

char datavalid();

void writetotalsf(ofstream& outfile);

None of these functions modify the object, so they should be declared
const. In fact, if validcount and invalidcount really are static, the
corresponding access functions can also be static.
};

int snowfall::eek:perator == (char str[])

// overloading operator == to compare two strings

Should return bool.
{
return (strcmp(date, str) == 0) ? 1 : 0;

"?1:0" is redundant. The result of strcmp()==0 is already true or false.
}

char snowfall::datavalid()
// checking to see both feet and inches are greater than 0, since they
can't
// be negative numbers.

{
char valid;

if ((ft >= 0) && (in >= 0.0f))
valid = 'T';
else
valid = 'F';
return valid;
}
Why not return bool?

....
// setting a loop to go 10 times since there will be maximum of 10
// records.

for (int i = 0; i <= 10; i++)

No it doesn't, it goes 11 times.
{
sf.readdata(infile);

// if dummy data, 00/00 is read, then variable i will be assigned
// 10 which will stop the loop.


No, it won't, because the loop is up to 10 *inclusive*.

If i is a counter, then use it as a counter, not as an end-of-loop flag.
Using one variable with two simultaneous meanings is evil. This
illustrates why: if you decide to change the number of records, you need
to change that "10" in two places.

If you want to terminate the loop early, the way to do it is to use
break.

I'll leave the rest, as others have already spotted some of the other
mistakes.
 

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

Forum statistics

Threads
473,995
Messages
2,570,231
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top