Hi all,
My code for a function to count words is posted below, and the only error that appears when I build it in my compiler is that char present is uninitialized. My program will not run with this uninitialized value. I've been searching for info on how to initialize my char present but have come up empty. The closest I've come is thinking that I may need to use a char pointer, but I'm not sure how to apply it in the context of this function. Any help is greatly appreciated.
Thanks.

int countWords(ifstream& fileName)
{
	int wordCount=0;
	char present;
	char next;
	
	fileName.get(next);
	while (!fileName.eof())
	{
		if((!isspace(present) && (present != '.') && (present != ',')) && (isspace(next) || (next == '.') || (next == ',')))
		{
			wordCount++;
		}
		present = next;
		fileName.get(next);
	}
	return wordCount;
}

Edited 4 Years Ago by engineerchica: add error appears when building

You can initialize present to '\0'. That won't compare equal to whitespace or any of you word boundaries, and it will immediately be reset to whatever the first character is.

I'd expect a warning but not an error for unitialized variable. You can initialize present and next to anything you want as long as you change it to a meaningful value before you try to use it. Initialize it to a tilde or an asterix or something if you want so it is easier to see if the default initialized value persists beyond expected interval.

I have rewritten it as displayed below which gets rid of the error, but now I'm getting an error during debugging pointing to a line in the int main(void) area.

int countWords(ifstream& fileName)
{
	int wordCount=0;
	char present;
	char next;
	
	fileName.get(next);
	while (!fileName.eof())
	{
		present = fileName.get();
		if((!isspace(present) && (present != '.') && (present != ',')) && (isspace(next) || (next == '.') || (next == ',')))
		{
			wordCount++;
		}
		present = next;
		fileName.get(next);
	}
	return wordCount;
}

Now, my whole program looks like this, and I get the following error message:
"Debug assertion failed!
Program: ...lab3n1.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\isctype.c
Line: 56
Expression: (unsigned)(c+1)<=256
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts."

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

void problems(char*);
int countChars(ifstream&);
int countWords(ifstream&);

int main(void)
{
	const char path[]={"D:\\filePath\\"};
	char fileName[32];
	char nameWithPath[81];
	int counter=0;

	cout<<"Enter the input file name: ";
	cin>>fileName;
	strcat(strcpy(nameWithPath,path),fileName); 

	ifstream inFile;
	inFile.open(nameWithPath);
	if (!inFile.good())
		problems(nameWithPath);

	cout<<"Number of characters: "<<countChars(inFile)<<endl;

	inFile.close();

	ifstream inFile2;
	inFile2.open(nameWithPath);
	if (!inFile2.good())
		problems(nameWithPath);

	cout<<"Number of words: "<<countWords(inFile2)<<endl;
	
	inFile2.close();

        return 0;
}

void problems(char* file)
{
	cerr<<"Problems opening file: "<<file<<endl;
	exit(EXIT_FAILURE);
}

int countChars(ifstream& fileName) 
{
	char c;
	int charCount=0;
	
	while(!fileName.eof())
	{
		c = fileName.get();
		if(c != '\n') 
			++charCount;
	}
	
	return charCount;
}


int countWords(ifstream& fileName)
{
	int wordCount=0;
	char present;
	char next;
	
	fileName.get(next);
	while (!fileName.eof())
	{
		present = fileName.get();
		if((!isspace(present) && (present != '.') && (present != ',')) && (isspace(next) || (next == '.') || (next == ',')))
		{
			wordCount++;
		}
		present = next;
		fileName.get(next);
	}
	return wordCount;
}

The logic for countWords is now broken because it throws away every other character.

Edited 4 Years Ago by deceptikon: n/a

I have trouble figuring out why you need both next and present in countWords, but that would seem to be a possible run time error as opposed to compile time error.

If you are obliquely asking for help in evaluating the error in main() then you will need to post the error and pertinent part of main() (or the entire thing if it isn't too long).

Edit:
Well fibber my gibbet. Looky there. My typing has really slowed.

Edited 4 Years Ago by Lerner: n/a

I think the problem still lies within my countWords function. After reviewing my while loop based on your comment, Lerner, I am confusing myself with what I'm trying to do. I don't just want to count spaces, but I want to count spaces which are followed by an alphanumeric character. This is because the last line in the file has about 12 extra spaces to center the last words. I am now re-evaluating this function.
Thanks for your feedback so far, everyone.

That if statement is rather hard to read. You could avoid using 'next' and 'present' and instead have a state variable that you set - eg 1st state = looking for a space, 2nd state = looking for next character. Then you could just read the next character in the file and process it based on the current state.
I can write and example if you would like.

Aah! chrisjubb! A new way of looking at it. I got stuck thinking about just the one way... Here is my new program which works correctly!!!

THANK YOU EVERYONE!

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

void problems(char*);
float countChars(ifstream&);
float countWords(ifstream&);

int main(void)
{
	const char path[]={"D:\\filePath\\"};
	char fileName[32];
	char nameWithPath[81];
	int counter=0;

	cout<<"Enter the input file name: ";
	cin>>fileName;
	strcat(strcpy(nameWithPath,path),fileName); 

	ifstream inFile;
	inFile.open(nameWithPath);
	if (!inFile.good())
		problems(nameWithPath);

	cout<<"Number of characters: "<<countChars(inFile)<<endl;

	inFile.close();

	ifstream inFile2;
	inFile2.open(nameWithPath);
	if (!inFile2.good())
		problems(nameWithPath);

	cout<<"Number of words: "<<countWords(inFile2)<<endl;
	
	inFile2.close();

        return 0;
}

void problems(char* file)
{
	cerr<<"Problems opening file: "<<file<<endl;
	exit(EXIT_FAILURE);
}

float countChars(ifstream& fileName) 
{
	char c;
	float charCount=0;
	
	while(!fileName.eof())
	{
		c = fileName.get();
		if(c != '\n') 
			charCount++;
	}
	
	return charCount;
}


float countWords(ifstream& fileName)
{
	float wordCount=0;
	char state, state2;
			
	while (!fileName.eof())
	{
		state = fileName.get();
		if(state == ' ')
		{
			state2 = fileName.get();
			if(state2 != ' ')
				wordCount++;
		}
	}
	return wordCount;
}

So if you were counting words in a theme paper you wouldn't want to count spaces as the only demarker of words because there are consecutive spaces at the end of each sentence? Only in your case there may be zero, one or more leading spaces in a line.

//don't count more than one space if they are consecutive 
get(first char) //get first char
while not at end of file //get all char in file
  if present char is space
    increase word count
    get(next char) //ignore any consecutive spaces
    if next char is space
      while not end of file and next is space
        fin.get(next)
    if end of file
      break out of loop
    else
      present = next //assign first non space char after space char(s) to present
  else
    fin.get(present)

Edit: Drat, beat again.

Edited 4 Years Ago by Lerner: n/a

Thanks, Lerner. I will review my function, again... It seems my function is about 11 words short of the actual count.

I appreciate your quick and useful help!!

Edited 4 Years Ago by engineerchica: Actually, my word count is off. Whoops.

My target word count is 107.
This is the function that returns 96 words.

float countWords(ifstream& fileName)
{
	float wordCount=0;
	char present, next;
			
	while (!fileName.eof())
	{
		present = fileName.get();
		if(present == ' ')
		{
		next = fileName.get();
		if (next != ' ')
			wordCount++;
		else
			present = next;
		}
			
	}
	return wordCount;
}

Here is my attempt at going with Lerner's help. So far it's returning 53.

float countWords(ifstream& fileName)
{
	float wordCount=0;
	char present, next;
			
	while (!fileName.eof())
	{
		present = fileName.get();
		if(present == ' ')
		{
			wordCount++;
		}
		if (present != ' ')
			next = fileName.get();
		{
			while(!fileName.eof() && next == ' ')
			{
			fileName.get();
			if(fileName.get() == EOF)
				break;
			else
				next = present;
			}
		}
			
	}
	return wordCount;
}

Any thoughts?

Edited 4 Years Ago by engineerchica: formatting

Try this;

fin.get(present); //get first char in file
while(!fin.eof()) //read all char in file
{
  if(present == ' ')
  {
    ++wordCount;    
    fin.get(next);

    //ignore any consecutive spaces    
    if(next == ' ')
    {
      while(!fin.eof() && next == ' ')
      {        
        fin.get(next);
      }
      if(fin.eof) 
        break;
      else
        present = next; 
    }   
    else      
      present = next 
   }
   else    
       fin.get(present);
}

post file to read

Edited 4 Years Ago by Lerner: n/a

Lerner, that code gets me 98 words, 9 short of the count MS Word gives me. I must be doing something else wrong.

Sorry! Missed that part.

Tom's most well, now, and got his bullet around his neck
on a watch-guard for a watch, and is always seeing what time
it is, and so there ain't nothing more to write about, and I
am rotten glad of it, because if I'd a knowed what a trouble
it was to make a book I wouldn't a tackled it and ain't agoing
to no more. But I reckon I got to light out for the Territory
ahead of the rest, because Aunt Sally she’s going to adopt me
and sivilize me and I can't stand it. I been there before.
THE END. YOURS TRULY, HUCK FINN.

Edited 4 Years Ago by engineerchica: The last line should have11 space before &quot;THE END...&quot;

The final line may not have a new line char, it may have EOF, so that will need to be considered as well.

Edited 4 Years Ago by Lerner: n/a

I have to run off to class, but I'm fairly confident that the \n was the other case I was missing.

Everyone, thank you THANK YOU for your help. I've learned A LOT working through this exercise and am so much better prepared for the next because of it.

This article has been dead for over six months. Start a new discussion instead.