Reading data from a file character by character to find word count

I need to have my program open a file and output how many words there are in the file. The catch is that my teacher wants us to pretend there are no "string" type so we need to read the file character by character. I tried to make it so the counter goes up every time there is a blank space in one variable but a character in the other; as well as when a variable is equal to the end of a line while the other is not a blank space. I'm not sure how to make it check if one variable is a character which might be better than

prevChar != ' '

I'm also not sure if i'm using the end of the line correctly with

currChar == '\n'

because this by itself

currChar == ' ' && prevChar != ' '

gives me 5 words for the first file and then i need the second part to give me two more for a total of seven.

This is my source code:

#include <iostream>
#include <fstream>
#include <cassert>
using namespace std;
int main()
{

ifstream infile;
char prevChar;
char currChar;
int count;
string fileName;

cout << "Enter the input file name: ";
cin >> fileName;
infile.open(fileName.c_str());


assert(infile);

count = 0;
infile.get(prevChar);
infile.get(currChar);

while (infile){
prevChar = currChar;

infile.get(currChar);

if ((currChar == ' ' && prevChar != ' ') || (prevChar != ' ' && currChar == '\n')

)
count++; // Increment counter
}

cout << count << " words." << endl;
system ("PAUSE");
return 0;

}


Below are the files my program opens and reads, they are all notepad documents
file1.txt
----starts below:
This &%file should!!,...



have exactly 7 words.
-----ends above

file2.txt

This is a &%file that should!!,...



have exactly 10 words.
---------

file3.txt:
This is a &%file that should!!,...


This file must have several spaces at the end of the file.
have 21 words.
---------

file4.txt
This &%file that has!!,...

'

This file must have several spaces at the end of the file.
19 words.
----------

file5.txt
Mr. &%Brown can moo!!,...

'

can you? This file should have several blank lines before the end of the file.

22 words.





-------this one ends after all those blank lines.

Hint: >>
hey helios, thanks for the hint but i dont know where to implement it, i'm a bit new a this.
Further hint:
Do you know what's wrong with this code?
1
2
3
std::string name;
std::cout <<"Enter your full name (surname, first name): ";
std::cin >>name;
If you don't, try it out.

operator>> is implemented for all input streams. std::ifstream is an input stream.
helios, did you read the first post?

The catch is that my teacher wants us to pretend there are no "string" type so we need to read the file character by character.
Soujirou, you should try a simple state machine. Something like this (pseudocode):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
enum {alnum, other} state = other;

int count = 0;

while(!eof)
{
   if(character is a digit or a letter)
   {
      if(state != alnum)
      {
         state = alnum;
         count++;
      }
   }
   else
   {
      state = other;
   }
}
Yes, I did, and your suggestion is retarded.
Care to elaborate?
Okay, it's not retarded, but it's inappropriate.

And about my example, the type I gave to 'name' is irrelevant. I could have given it char[1000] without changing the point of the example.
I agree that your method is simpler, and I would recommend it, but

The catch is that my teacher wants us to pretend there are no "string" type so we need to read the file character by character.

I'm sure Soujirou's teacher thought about every type which is kind of "string" type, including old fashioned array of characters. Without this restriction the problem would be just too easy.
Actually, I didn't think about that. I thought the restriction was to demonstrate a possible use of >>, but now that you mention it, you may be right.
Thank you helios and Abramus for helping to try and figure this out. I'm not at home so i can't try the suggestion out but these are my teacher's instructions:

"Repeat assignment 5.4, but pretend that the string type does not exist. You will have to input the data one character at a time. This approach is much more difficult than the approach used in part 4. Here are some hints for assignments 5.4 and 5.5.

You should, of course, continue to use a string variable for the name of the file."

The hints were:

"Here's a basic structure for a program that processes a file (by this I mean opens a file and then uses a while loop to go through the entire file). This is what you'll have to do in this exercise (and what you'll have to do often in programs that involve files).

First, don't forget to include fstream as well as iostream at the top. Also, in order to use the assert function call described below, you'll have to have a #include <cassert> at the top of your program. Here's what main might look like.
int main()
{
string astring;
ifstream infile; // step 1: declare a file variable


infile.open("myfile.dat");
// step 2:
//open a file. myfile.dat is a text file
//that you created by yourself. You could
//use the CodeWarrior editor to make it,
//or you could use a word processor and
//choose "save as text" when you save it.
//make sure it is in the
//same folder as your project. From now
//on in your program, you won't use the
//actual name of your file, you'll
//use "infile".


assert(infile);
// step 3:
//I use this statement, instead of the if statement
//you'll find in the text, to make sure the file really
//opened. If it didn't, your program will stop and
//you'll get an error message "assert ..... failed"

infile >> astring;
// step 4: start reading from the file

while (infile){
//this condition will become false when you have
//read beyond the end of the file

<process astring>
infile >> astring;
}
}

Notice that the loop look a lot like a special value type loop (you get input before the loop and at the bottom ot the loop). It's the same idea. The last time you go to get input, you read past the end of the file, and so the loop stops.

Your code will look a lot like this. Just replace <process astring> with whatever it is you want to do each time you read a string. (add one to a wordcounter????? hint hint).

If you keep getting the message that the assert failed, it is almost certain that you have saved your input file in the wrong place. The input file should be saved in the folder where your project is saved. If you have this problem and can't get it straightened out, don't waste hours on it. Ask me for help.

Important: Because you are using the same ifstream variable to link to several different files as your program runs, you will need to place calls to the functions .close() and .clear() at the bottom of your loop so that the ifstream variable can be reused next time around. If the name of your ifstream variable is infile, for example, the statements would be

infile.close();
infile.clear();

The details: when you reach the end of the file, what actually happens is you send the ifstream variable into an error state. Before you can use the ifstream variable again, you have to get it out of the error state. This is what the .clear() function does.

When you get to part 5, you'll have to replace the string with a character variable. Your loop won't change, but instead of adding 1 to your word counter every time through your loop, you'll want to add 1 to your wordcounter only if the current character is a space or a newline, and the previous character was NOT a space or a newline. This will look an awful awful awful awful lot like the loop on p. 291 of the 2nd edition (pp. 275 - 276 in the 3rd edition). "



I'm thinking maybe i need to replace:

if ((currChar == ' ' && prevChar != ' ') || (prevChar != ' ' && currChar == '\n')

with:

if ((currChar == ' ' || currChar '\n') && (prevChar != ' ' || prevChar != '\n'))

stil not working :/
anyone know how i can fix it?
This is what i changed it to:

if ((currChar == ' ' && prevChar != ' ') || ( currChar '\n' && prevChar != '\n'))


and it gets the word count right for the first file but over shoots the rest :/ any more restrictions i need to put?

Topic archived. No new replies allowed.