• Popular Now

• 13
• 18
• 19
• 27
• 9

Archived

This topic is now archived and is closed to further replies.

Real Simple For You, Real Confusing For Me

This topic is 5242 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I''ve been banging my hand against a wall trying to figure out what is wrong with this program and I can''t do it. All my books are no help on this matter. (FYI this is problem 7 from Chapter 7 of Malik''s C++ Programming: From Problem Analysis to Program Design. I''d ask my teacher, but I''m teaching myself. The assignment is to open up a text file, read the contents of it (while counting the number of words, lines, and paragraphs) and then output the text into another document along with the relevant counts at the end of the file. Two problems: 1. It runs in an infinite loop (printing the very last character) unless there is a newline character at the very end of the input file. 2. It won''t copy over the spaces or newline characters. So it just prints a string of letters. So, the file: The dog ran into the street. The cat is blue.\n Get''s returned as: Thedogranintothestreet.Thecatisblue. Total number of words: 1. Total number of lines: 1. Total number of paragraphs: 9. Again, if there isn''t that newline character, it gives me an endless string of periods. Feel free to bust on me for the code. But I''d really appreciate knowing why the blanks aren''t copying and why it goes into an infinite loops. Thanks in advance.

#include<fstream>
#include<iostream>

using namespace std;

void initialize(int& x, int&y, int& z, int&w);
void processBlank(ifstream& in, ofstream& out, char& ch, int& w);
void copyText(ifstream& in, ofstream& out, char& ch);
void updateCount(int& wordsLine, int& wordsTotal, int& linesTotal, int& paraTotal);
void printTotal(int& wordsTotal, int& linesTotal, int& paraTotal, ofstream& y);

int main()
{
int wordsLine = 0;
int wordsTotal;
int linesTotal;
int paraTotal;
char letter;

ifstream inData;
ofstream outData;

inData.open("E:inData.txt");
outData.open("E:outData.dat");

initialize(wordsLine, wordsTotal, linesTotal, paraTotal);

inData.get(letter);

if ((letter != '' '') && ((letter != ''\n'') && (letter != ''\t'')))
++wordsLine;

while (inData)
{
processBlank(inData, outData, letter, wordsTotal);
copyText(inData, outData, letter);
updateCount(wordsLine, linesTotal, paraTotal, wordsTotal);
inData.get(letter);
}

printTotal(wordsTotal, linesTotal, paraTotal, outData);

inData.close();
outData.close();

cout << endl;
return 0;
}

void initialize(int& x, int&y, int& z, int& w)
{
x = 0;
y = 0;
z = 0;
w = 0;
return;
}

void processBlank(ifstream& in, ofstream& out, char& ch, int& w)
{

while ((ch == '' '') || (ch == ''\t''))
{
out.put(ch);
in.get(ch);

if ((ch != '' '') && ((ch != ''\n'') && (ch != ''\t'')))
++w;
}

return;
}

void copyText(ifstream& in, ofstream& out, char& ch)
{
while ((ch != '' '') && ((ch != ''\n'') && (ch != ''\t'')))
{
out.put(ch);
in.get(ch);
}
return;
}

void updateCount(int& wordsLine, int& linesTotal, int& paraTotal, int& wordsTotal)
{
wordsTotal += wordsLine;
if(wordsLine == 0)
++paraTotal;
else
++linesTotal;
wordsLine = 0;
return;
}

void printTotal(int& wordsTotal, int& linesTotal, int& paraTotal, ofstream& y)
{
y << endl << "Total number of words: " << wordsTotal << ".";
y << endl << "Total number of lines: " << linesTotal << ".";
y << endl << "Total number of paragraphs: " << paraTotal << ".";
return;
}


Share on other sites
I think you''re losing a blank character in CopyText (reading a space breaks the loop, but that character is not sent to the output).

You get into an infinite loop in copyText, because you''re not checking for the EOF character.

Share on other sites
You''re right about the copying the variable. The last line in the while loop in main enters in a new character, so the whitespaces get deleted before they get back to the processBlank function.

Thanks.

However, if I delete the line that gets the next character, then I get back into an infinite loop. I switched the condition on the while loop of main over to (!inData.eof()) but that doesn''t fix it.

Do you have any other ideas?

Share on other sites
OldGuy,
Thanks for the help. I kept at it thinking about the points that you raised and now it is working fine.

I set up a second character variable and used it with peek to have it test for the end of the file. It''s working fine now.

Share on other sites
What are you compiling this under? I copied your code and compiled it under g++ and it didn't infinitely loop.

EDIT: I should also add, I mean that it did not loop when I had just "The dog ran into the street.
The cat is blue." in the file.

[edited by - suikio on November 6, 2003 12:49:24 AM]

Share on other sites
I compiled it under Visual C++ 6.

My basic diagnosis is that somehow get was not recording that the ifstream had reached the end of the file. Do you know anything about that?

Share on other sites
It doesn''t see you''re reaching enf-of-file since you''re not checking for it.

while (instream) does not check for end-of-line. In fact, I''m surprised your compiler doesn''t bitch and moan about it - you''re downcasting a stream to a boolean expression.

Share on other sites
quote:
Original post by groby
It doesn''t see you''re reaching enf-of-file since you''re not checking for it.

while (instream) does not check for end-of-line. In fact, I''m surprised your compiler doesn''t bitch and moan about it - you''re downcasting a stream to a boolean expression.

http://www.research.att.com/~bs/bs_faq2.html

Share on other sites
quote:
Original post by groby
It doesn''t see you''re reaching enf-of-file since you''re not checking for it.

while (instream) does not check for end-of-line. In fact, I''m surprised your compiler doesn''t bitch and moan about it - you''re downcasting a stream to a boolean expression.

One of the base classes of ifstream, the basic_ios class, defines two operators the void* operator() and the bool operator!(). The fist operator returns a null pointer if the function fail() returns false, that is if rdstate or failbit is set. That happens if eof is true. So using while(instream) is perfectly legal. Don''t ask me why they decided to use a void pointer instead of bool though.

The other operator (bool operator!()) returns true if the stream is not bad, again using fail().

Share on other sites
Thanks for all the responses.

Groby, thanks for the point on while(instream) not checking for the end of the file. However, I had originally include (!inData.eof()) as the condition on that while loop and I still had the same problem.

Anonymous Poster, thank you for that link. Now I have a good place to go before I clog up the forum with uninteresting questions.

fredizzimo, I''m only seven chapters into a baby-C++ book. I haven''t done any work with classes yet. I would really appreciate it if you could dumb it down a bit.

Again, thanks.