solved

Hello everyone. I have a homework assignment that asks to input a string of up to 132 characters in length. I am asked to pass the input into an array and then count how many of each individual uppercase/lowercase/number appear within the string. For example, this is what is expected for the output:

Enter a string of up to 132 characters in length: "I ate 6 apples."
I - 1 time
a - 2 times
e - 2 times
p - 2 times
6 - 1 time
etc...

I have two arrays: one which takes in the string and another that counts each occurrence of each individual uppercase/lowercase/number in the entered string.
I am struggling most with getting the counting array to count each occurrence. Here's the code that I have right now( it does not account for output yet):

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
#include <iostream>
using namespace std;

void Count(char c_input[], int l_count[]);


int main()
{
	const int size = 132;
	char CharInput[size] = { 0 };
	int LetterCount[size] = { 0 };

	cout << "Enter a string of up to 132 characters in length: ";
	cin.getline(CharInput, size);
	cout << "You entered: " << CharInput << endl;
	
	Count(CharInput, LetterCount);

	system("pause");
	return 0;
}

void Count(char c_input[], int l_count[])
{
	for (unsigned int i = 0; c_input[i]!='\0' ; i++)
	{
		l_count[i] = 0;

		for (int x = 0; x<26; x++)
		{
			if (c_input[i] == 'a'+x)
				l_count[i]++;
		}
		cout << l_count[c_input[i]-'a'] << endl; // testing count
	}
}


Can anyone provide any advice or suggestions as to how I can get the counter to count each letter? I am aware of using #include <map> but I am not allowed to use it on this assignment. Thank you all for the help.
Last edited on
To accomodate a c-style string of 132 characters, you need 133 characters; one extra for the terminating '\0' character.

It doesn't make sense to make the count array 132 (or 133) in size. The size of the input buffer has nothing to do with how many counters you need for the different letters.

In Count in the loop going through all the lowercase letters, the upper bound should be x < 26 ('a' + 25 == 'z').

But that's actually an overly-complex way of doing it. You could do this instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

void CountLetters(char input[], int count[]) {
	for (int i = 0; input[i]; i++)
	    if (input[i] >= 'a' && input[i] <= 'z') // lowercase
	        count[input[i] - 'a']++;
}

int main() {
	const int Size = 133;
	char input[Size] {};
	int  count[26]   {};

	cout << "Enter a string of up to 132 characters in length: ";
	cin.getline(input, Size);

	CountLetters(input, count);

	for (char ch = 'a'; ch <= 'z'; ch++) cout << ch << ' '; cout << '\n';
	for (int x = 0; x < 26; x++) cout << count[x] << ' '; cout << '\n';
}

I like the code! Just three things I am curious about:

1: What is the purpose of subtracting the letter 'a' from input[i] within that function CountLetters? Is it somehow related to the ASCII value of 'a' (which I believe is 97)?

2:For uppercase and number occurrences, would I use the same setup similar to the for loop in your function? for example, I created two separate arrays for uppercase and number counts.

3: How could I rewrite the last two lines of code within your main function to output similar to my first post? Your example displays occurrences in two long lines of code, I just want to make it look a bit nicer.

Here's the edits I made to what you sent. I added more for loops to account for uppercase occurrences and number occurrences. I want to get this to work so I could create a similar setup in my assignment.
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
39
40
41
42
43
44
#include <iostream>
using namespace std;

void CountLetters(char input[], int u_count[], int l_count[], int n_count[]) {
	for (int i = 0; input[i]; i++)
	{
		if (input[i] >= 'a' && input[i] <= 'z') // lowercase
			l_count[input[i] - 'a']++;
	}
	for (int i = 0; input[i]; i++)
	{
		if (input[i] >= 'A' && input[i] <= 'Z')
			u_count[input[i] - 'A']++;
	}
	for (int i = 0; input[i]; i++)
	{
		if (input[i] >= 0 && input[i] <= 9)
			n_count[i]++;
	}
}

int main() {
	const int Size = 133;
	char input[Size]{};
	int  upper_count[26]{};
	int lower_count[26]{};
	int num_count[10]{};

	cout << "Enter a string of up to 132 characters in length: ";
	cin.getline(input, Size);

	CountLetters(input, upper_count, lower_count, num_count);

	for (char ch = 'a'; ch <= 'z'; ch++)
	{
		for (int x = 0; x < 26; x++)
		{
			if (upper_count[x] > 0)
				cout << ch << " - " << upper_count[x] << " times.\n";
		}
	}
	system("pause");
	return 0;
}


Thank you for your time!
chars are ultimately small integers. As long as the values for 'a' ... 'z' are contiguous, then subtracting the lowest value will give you a number from 0 to 25, which is what you need for the index. Same with 'A'...'Z' and '0'...'9'. (*but see Note below*)

For the digits, you need to compare to '0' and '9', not 0 and 9. And you'll need to subtract '0' for digits to use it as an index (or add '0' to print out the character from the index).

You've got the print out almost right. You don't need the outer loop (going from 'a' to 'z').

1
2
3
    for (int i = 0; i < 26; i++)
        if (lower_count[i] > 0)
            cout << char('a' + i) << " - " << lower_count[i] << " times.\n";


*Note* Actually, we can't be absolutely certain 'a' to 'z' (or 'A' to 'Z') are contiguous since there exist character sets where it isn't true (e.g., EBCDIC). Only '0' to '9' are guaranteed to be contiguous in C/C++. However, in the character codes we commonly use (such as ASCII and UTF-8), the alphabetic characters are contiguous.
Last edited on
I got a working function! Thanks for the short example! I was able to build from your edit and pass the output into its own seperate function! Thanks for all the help!
With your CountLetters function, can you see how it would be better to have 1 for loop with 3 if statements?
Topic archived. No new replies allowed.