Can anyone help with this?

so I have to write a program that checks a file for the amount of characters(a-z capital and lower 0-9 and some other symbols) and i got everything else working and it reads the file and checks and outputs values but the values fluctuate around the correct values so some will be above by a few and less by a few and i dont know why.

if anyone could help it would be much appreciated

this is the code for reading in the characters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void countChars(charholder& chars, string& filename, ifstream& infile,
 ofstream& outfile, int wordcount)
{
	//counting # of specific chars in file 
	for (int pos = 0; pos < 57; pos++)
	{
		infile.open(filename);
		if (!infile)
		{
			cout << "Can't open file";
		}
		char text;
		while(!infile.eof())
		{
			infile >> text;
			infile.ignore(200, chars.lower[pos]);
			chars.count[pos]++;
		}

		infile.close();
	}
	for (int pos = 0; pos < 26; pos++)
	{
		infile.open(filename);
		if (!infile)
		{
			cout << "Can't open file";
		}
		char text;
		while(!infile.eof())
		{
			infile >> text;
			infile.ignore(200, chars.upper[pos]);
			chars.count[pos]++;
		}
		infile.close();
	}
}


this is in a function inside the code and chars is a struct that has spaces for all the characters and to hold how much of each there are.
Last edited on
Do not loop on (! stream.eof()) or (stream.good()). This does not work the way you expect. The eof bit is set true only after you make a read attempt on the file. This means after you read the last record of the file, eof is still false. Your attempt to read past the last record sets eof, but you're not checking it there. You proceed as if you had read a good record. This will result in reading an extra (bad) record. The correct way to deal with this is to put the >> (or getline) operation as the condition in the while statement.
1
2
3
  while (stream >> var) // or while (getline(stream,var))
  {  //  Good operation
  }


PLEASE ALWAYS USE CODE TAGS (the <> formatting button) when posting code.
It makes it easier to read your code and also easier to respond to your post.
http://www.cplusplus.com/articles/jEywvCM9/
Hint: You can edit your post, highlight your code and press the <> formatting button.

No clue what a charholder is since you don't include the declaration for it.

Why are reading the file inside a for loop?
Last edited on
charholder is a struct that has arrays which have the letters and symbols that im looking for and different arrays that hold how many times each one shows up in the file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct charholder
{
	char lower[58]
	{ 
		'a','b','c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
		'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '?', ',', '.', ':', ';',
		'_', '"', '@', '$', '#', '%', '&', '*', '(', ')', '+', '=', '/', '-', '<', '>' 
	};
	char upper[26]
	{
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
	};
	double	count[58]
	{ 
		0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
	};
	double percent[58]
	{ 
		0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
	};
};


I had to put the open file inside the for loop because for whatever reason when i put it before or at the start of the function it just wasn't open when i went inside the for loop. so i put it in there and it works so idk.

For the way that your showing to use the while loop what do i put in place of "var"?

Thank you for the help and insight, I'm pretty new to this so its much appreciated.
stealman799 wrote:
For the way that your showing to use the while loop what do i put in place of "var"?

var stands for whatever variable you're reading into. In the case of lines 15 and 32, you're reading into text.

Thanks for adding code tags.

stealman799 wrote:
I had to put the open file inside the for loop because for whatever reason when i put it before or at the start of the function it just wasn't open when i went inside the for loop.

The open should not act any differently inside or outside the loop.



OMG. Have an array that is indexed by the ASCII value of the read char. That will count the number of each char in the file. If you then want specific info ie re upper-case chars, then this can be extracted from the read array. Something like this which will populate the array chars with the count of each char found in the file and display the count of digits:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>
#include <cctype>

int main() {
	unsigned chars[256] {};
	std::ifstream ifs("mytest.txt");

	if (!ifs)
		return (std::cout << "Cannot open file\n"), 1;

	for (char ch{}; ifs.get(ch); ++chars[static_cast<unsigned char>(ch)]);

	for (unsigned c = 0; c < 256; ++c)
		if (chars[c] && std::isdigit(c))
			std::cout << static_cast<unsigned char>(c) << ' ' << chars[c] << '\n';
}


Which for my test file displays:


1 1
2 1
3 1
4 1
5 1
6 2
7 4
8 3
9 1

Topic archived. No new replies allowed.