Working with arrays

Hello. I'm new here. I need guidance with a program I'm working on for a c++ lab. Thanks in advance.

The program is quite simple...yet complicated for me because I've just started taking one dimension arrays in class and suddenly the lab threw this small project at me.

I have to write a program that asks the user to enter his/her name, then the program will print the name followed by a list of the letters that the user entered(if they repeat themselves then it will add 1 instead of printing it again.)

example:

What is your name?: Luis Pantoja

The name you've entered is: Luis Pantoja.

The letter l appeared 1 time.
The letter u appeared 1 time.
The letter i appeared 1 time.
The letter s appeared 1 time.
The letter p appeared 1 time.
The letter a appeared 2 times.
The letter n appeared 1 time.
the letter t appeared 1 time.
The letter o appeared 1 time.
The letter j appeared 1 time.

P.S. I asked my c++ programming class professor and she mentioned something about changing all chars to lowercase so that the array won't get confused. Then to create two parallel arrays...one char array to store the letters that aren't repeated and one int array (with all values being zero but adds 1 when a letter is new or if a letter repeats)...I don't know how to do the parallel thing.


Here's what I've managed to come up with so far, I think i need to make a loop inside a loop, but i don't know how to begin the code...

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

int main() {

	const int size = 30;
	char name[size];
	char namelc[];
	int freq[];
	int i;
	

	cout << "What is your name?: ";
	cin.getline (name,size,'\0');

	cout << "Your name is: " << name << ".\n";

	for (i = 0; i != '\0'; i++) {
		tolower(name[i]);
	}

	//print
	for (i = 0; i != '\0'; i++) {
		cout << "The letter " << namelc[i] << " appears " << freq[i];
		if (freq[i] == 1) {
			cout << " time." << endl;
		}//end if
		else {
			cout << " times." << endl;
		}//end else

	}//end for

	system("pause");
	return 0;

}//endmain 



Edit: Just made this up, but I'm not sure if it makes any sense.(Don't want it to count whitespaces...idk how the code works because I haven't be taught yet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (i = 0; i != '\n'; i++) {

		if (iswspace(name[i]) {
			skipws;
		}
		else {
			if (name[i] == namelc[i]) {
				freq[i]++;

			}
			else {
				name[i] = namelc[i];
			}
		}
	}
Last edited on
The arrays
1
2
	char namelc[];
	int freq[];
don't have any size, thus are not valid. These will be used to store the characters of the name, the size won't be greater than the number of letters in the name, so you could make them each the same as the length of the input array
1
2
    char namelc[size];
    int freq[size];
If the arrays are a bit larger than required it doesn't matter.

This line is not correct:
 
    cin.getline (name,size,'\0');
the getline needs to check for the newline delimiter, '\n'. But since that is the default, it can be omitted, giving simply
 
    cin.getline (name, size);


This loop doesn't change the character to lower case:
1
2
3
    for (i = 0; i != '\0'; i++) {
        tolower(name[i]);
    }
because you need to store the value returned by the function,
 
    name[i] = tolower(name[i]);


Also the for-loop condition is incorrect.
 
    for (i = 0; i != '\0'; i++)
should be
 
    for (i = 0; name[i] != '\0'; i++)


Next, you need to loop through the name again. This time, you need to search the array namelc to see whether the character is already stored there.

How would you do that? It will require a loop inside a loop. The array has a size of size but how many of those are in use? You need a counter, such as int count = 0; then have a loop that checks each character from 0 to count. If the character is not found, store the char in namelc[count], store the integer 1 in freq[count], and add 1 to count. But if the character is found, simply add 1 to freq[k] where k is the subscript of the matched character.

When the whole of the name has been processed, loop through the arrays from 0 to count-1, printing out the character and its frequency value.

I didn't mention skipping spaces here - I'd add in the check for that after the main structure has been coded.

Last edited on
First I want to thank you for taking some of your time to help me with my problem.

This is how the code looks so far, but my gut is telling me I'm doing something wrong in the for loop, but I can't tell what it is...

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
45
46
47
48
49
50
51
52
53
54
#include<iostream>
#include<cctype>
using namespace::std;

int main() {

	const int size = 30;
	const int frequency = 1;
	char name[size];
	char namelc[size];
	int freq[size];
	int i;
	

	cout << "What is your name?: ";
	cin.getline (name,size);

	cout << "Your name is: " << name << ".\n";

	for (i = 0; name[i] != '\0'; i++) {
			name[i]=tolower(name[i]);
	}

	for (i = 0; name[i]!='\0'; i++) {
		
		for(int count=0;namelc[count]!='\0';count++)
		{
			if (namelc[count] != name[i]) {
				namelc[count] = name[i];
				freq[i] = 1;
				break;
			}
			else {
				freq[i]++;
			}
		}
	}

	//print
	for (int count = 0; name[count] != '\0'; count++) {
		cout << "The letter " << namelc[count] << " appears " << freq[i];
		if (freq[i] == 1) {
			cout << " time." << endl;
		}//end if
		else {
			cout << " times." << endl;
		}//end else

	}//end for

	system("pause");
	return 0;

}//endmain  


The output confirms that I'm doing something wrong...

Here's the output:
What is your name?: Luis Pantoja
Your name is: Luis Pantoja.
The letter a appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
The letter ╠ appears -858993460 times.
Press any key to continue . . .
Probably I didn't describe very well what needs to be done. Your code is using the variable count in a way quite different to what I intended.

What I meant was, define it before starting to store anything in the arrays freq and namelc.

The arrays are like this:
1
2
char namelc[size];
int freq[size];
but to begin with, none of the array is in use, hence
 
int count = 0;


The loop within a loop, looks like this:
1
2
3
4
5
6
7
8
    for (int i = 0; name[i] != '\0'; i++)
    {
            
        for (int k = 0; k<count; ++k)
        {
        // code omitted here
        }              
    } 

You might ask, what's the point of that, the inner loop won't even execute at all. That's true, at first.

Let's fill in the details a little bit:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    for (int i = 0; name[i] != '\0'; i++)
    {           
        bool found = false;
     
        for (int k = 0; k<count; ++k)
        {
            if (namelc[k] == name[i])
            {
                found = true;
            }
        }

        if (!found)
        {

        }
    } 

Above, there is a boolean named found which is used so we can tell whether the letter was found or not.

If the letter was found, at line 9 where the flag is set to true, add 1 to freq[k].

If the letter was not found, at line 15,
1
2
3
namelc[count] = name[i]; // store the letter because it was not found
freq[count] = 1;   // count is 1 because this is the first time
count++;   // add 1 to show how many rows of the arrays are being used. 


Does that make any sense? Here it is all together:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    int count = 0;
    
    for (int i = 0; name[i] != '\0'; i++)
    {
        if (isspace(name[i]))
            continue;
            
        bool found = false;
        for (int k = 0; k<count; ++k)
        {
            if (namelc[k] == name[i])
            {
                found = true;
                freq[k]++;
            }
        }

        if (!found)
        {
            namelc[count] = name[i];
            freq[count] = 1;
            count++;
        }                
    }   




Eventually after the looping is completed, the value of count will represent how many unique characters were in the original name. Just loop through the arrays namelc/freq to display what was stored, and the frequencies.
Last edited on
wow, I interpreted it wrong.

I can't believe I forgot this:

The loop within a loop, looks like this:

1
2
3
4
5
6
7
8
for (int i = 0; name[i] != '\0'; i++)
    {
            
        for (int k = 0; k<count; ++k)
        {
        // code omitted here
        }              
    }


It was basic "for" stuff I learned last trimester.


It's the first time I've seen bool, I don't know why the professor skipped it, but i think I understood it...basically, found is false until a condition is met(like namelc[]=name[]), right?...What about the "continue"? What does that do?

Last edited on
See "The continue statement" http://www.cplusplus.com/doc/tutorial/control/
The purpose here is to skip the rest of the loop when a space character is found - which I think was the requirement?

bool - you could use a char or an int here, for example char found = 'F'; // false and found = 'T' to represent true. It's simply a way of keeping track of the state of the program, in this case it 'remembers' whether the item was found or not. The advantage of bool is that it has just two values, true and false, and the intention should be clear to the reader, whereas something like int found = 533; would be mysterious and puzzling, though it might do the same job.

basically, found is false until a condition is met
yes, it keeps its current value unless something in the program changes it by assigning a new value.

How do I make it stop at the last letter in the print loop?

namelc[count]!='\0'

doesn't seem to do the trick.
How do I make it stop at the last letter in the print loop?

namelc[count]!='\0'

doesn't seem to do the trick.

Checking for a null character is somewhat of a special-purpose use. It applies only when we are dealing with character strings, such as "Hello World", which will always have a non-displayed '\0'. But in this example, the array isn't a string, it's just a collection of individual characters. Fortunately there's another way to know when to stop.

Remember this?
1
2
3
4
    for (int k = 0; k<count; ++k)
    {
        // code omitted here
    } 
ooooooooooooooooooooooooooooooh, so if the count variable from the previous loop isn't altered, it will still hold the number of the last subscript from the array namelc...of course, of course...

So this will do:

1
2
3
4
5
6
7
8
9
10
11
12
for (int k = 0; k != count; k++) {
		
		cout << "The letter " << namelc[k] << " appears " << freq[k];
		
		if (freq[k] == 1) {
			cout << " time." << endl;
		}//end if
		else {
			cout << " times." << endl;
		}//end else

	}//end for 


Well I think that pretty much does it...You helped me quite a lot and taught me a few things. I can't thank you enough. Thank you for everything!

Edit:
LOL, you mentioned that at the end of the previous response...
Last edited on
You're welcome. I think it isn't easy to get to grips with this stuff, it can seem like lots of disconnected fragments that don't always seem related. After a while it should start to join together and a bigger picture emerges.
Topic archived. No new replies allowed.