Baby names assignment using structs strings and files

Pages: 1234
kemort,

Gotcha. I'm getting an error here: if(!strcmp(search_name, aList[i].name))

Saying strcmp wasnt declared in the scope?

EDIT: sorry, fixed. Added #include <cstring>

So now I have an idea of what the histogram is like. However it is giving me weird errors and looks funky if I dont enter it in exactly like the name in the text file.

1
2
3
4
5
6
7
8
9
10
11
12
13
Please enter a name: wAlter
   0: 
   0: 
2130567168: 
2686792: 
4199691: 
2346776: 
4429: 
  -1: 
   0: 
   0: 
   0: 

Last edited on
closed account (48T7M4Gy)
Well done.

You should be starting to see why the menu can be left till later - just get the functions working.

Hint: To allow for WaLTeR you convert each character in the name to upper (or lower) case for both c-strings in the strcmp function. It's just a couple of extra lines in the find function.

Also, look at what the find function returns if no name is in the list. So ... in main
1
2
3
4
if(found_index != -1)
        displayPersonHistogram( list, number_of_names, found_index);
    else
        cout << "Name not found\n";
Last edited on
kemort,

Yeah I can see why the menu can wait until later.

That function is interesting. What does the negative 1 mean I haven't seen that before.

Is it possible to incorporate toupper and tolower into that? I tried messing around in the find function using tolower but havent had much luck
closed account (48T7M4Gy)
The -1 is a dummy index, it's common practice - good to know, so that if a name isn't found in the list the function returns an impossible array index ie -1.

So you can check if you get -1 in main and act accordingly. You can choose any impossible number you like to initialize the variable index. It could be 5001 as long it is outside the possible range of the array.

I'm giving you too much but I just updated to show you one way with changing case.



Oh that's neat :) Thank you for your help!

What does this mean?
1
2
3
 warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0; i < strlen(aName); i++)
                      ^
closed account (48T7M4Gy)
The warning is because int is being compared to what strlen function actually returns which is type size_t

You can ignore the warning if you like, I did because it makes the code look more complicated than it is. But now that you are an expert on this :) you can write

for(size_t i = 0; ... etc)

See:
http://www.cplusplus.com/reference/cstring/strlen/?kw=strlen
http://www.cplusplus.com/reference/cstddef/size_t/?kw=size_t
Thank you kemort :)

Next up is comparing two names in a decade. This is what the output is supposed to look like:
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

    Select a menu option:
       a - Print histogram for a name
       b - Compare two names in a decade
       c - Print top ten names for a decade
       d - Quit (write anomalies)
    Your selection: b
    Enter a name: cAthY
    Enter a name: toDD
    Enter number corresponding to your decade:
        1 - 1900-1909
        2 - 1910-1919
        3 - 1920-1929
        4 - 1930-1939
        5 - 1940-1949
        6 - 1950-1959
        7 - 1960-1969
        8 - 1970-1979
        9 - 1980-1989
       10 - 1990-1999
       11 - 2000-2005
    Enter a decade: 8
    
    Data for Cathy
     215: *******************************************************************************
    
    Data for Todd
      43: ************************************************************************************************


I have this so far:
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
int compareTwoNames( Name aList[], int actual_number_names)
{
	
	  	int index = -1;
	    char search_name[NAME_LEN];
	    char search_name2[NAME_LEN];

	    cout << "Enter a name: ";
	    cin >> search_name;
	    convertToUpperCase(search_name);
	    
	    cout << "Enter a name: ";
	   	cin >> search_name2;
	   	convertToUpperCase(search_name);
	    

	   	cout <<"Enter number corresponding to your decade: \n";
	   	//cin >>
	   	// cout >>" Enter a decade: ">> " " >> endl;
	   	
	   	
	    char list_name[NAME_LEN];
	    for(int i = 0; i < actual_number_names; ++i)
	    {
	        strcpy(list_name,aList[i].name);

	        convertToUpperCase(list_name);

	        if(!strcmp(search_name, list_name))
	        {
	            cout << "Histogram for name, "<< search_name<<endl;
	            cout << "Histogram for name, "<< search_name2<<endl;
	            index = i;
	            return index;
	        }
	    }
	    return index;
	}
	


I was going to write a switch statement for the decade part
closed account (48T7M4Gy)
The way I read this part you have to get two names and then compare the rankings of each for each decade. You're not required to compare the two names because they are already known to be different.
Why would you compare Walter with Walter?

So, if I'm right, you get the two names in the form of their index in the list, name1index and name2index and work from there.

aList[name1index].rank[0] etc is a critical part here for you to think about in comparing it to
aList[name2index].rank[0] etc
closed account (48T7M4Gy)
Also, read the findName function very carefully. It has the question built in to it, including the case conversion. It returns the index in the list which is all you need to get the name and full rankings for all decades. You can select which decade you want in the next step.
kemort,

I kinda figured it would have to be something to do with that function. So something like int name1index and int name2index? Or would they be char? Do I need another for loop?

Or could I do a cin for aList[name1index].rank[0]?
closed account (48T7M4Gy)
It would be like in my main, int name1index = findName( ...
Okay I'll mess around with it
Yeah I'm lost..

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
int compareTwoNames(Name aList[], int actual_number_names) {

	int index = -1;
	int name1index;
	int name2index;


	cout << "Enter a name: ";
	cin >> name1index;
	//convertToLowerCase(name1index);

	cout << "Enter a name: ";
	cin >> name2index;
	//convertToLowerCase (name2index);

	cout << "Enter number corresponding to your decade: \n";
	//cin >>
	//cout >>" Enter a decade: ">> " " >> endl;

	char list_name[NAME_LEN];
	for (int i = 0; i < actual_number_names; ++i) {
		strcpy(aList[name1index].rank[0],aList[name2index].rank[0]);

				convertToLowerCase(list_name);

				if (!strcmp(name1index, list_name)) {
					cout << "Histogram for name, " << name1inedx
							<< endl;

					index = i;
					return index;
				}
				// if(!strcmp(search_name2, list_name))
				//  {

				//	convertToLowerCase(list_name);
				//   cout << "Histogram for name, "<< search_name2<<endl;

				//   index = i;
				// return index;
				// }
			}
			return index;
		}
Last edited on
Kemort did you delete your post?

edit:
The last thing I saw before you edited/deleted was this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void compareTwoNames(Name aList[], int actual_number_names) {
	//FIRST NAME
	int name1Index = findName(aList, actual_number_names);

	if (name1Index != -1) {
	cout
	<< "I have just found " << aList[name1Index].name << '\n'
	<< "Ranking 0 is: " << aList[name1Index].rank[0] << '\n'
	<< "Corresponding histogram is:\n"
	<< displayPersonHistogram(aList[], actual_number_names, name1Index);
} else
	cout << "Name not found - try again\n";

}

which is giving me this error
1
2
error: expected primary-expression before ']' token
         << displayPersonHistogram(aList[], actual_number_names, name1Index);
Last edited on
closed account (48T7M4Gy)
Yeah, I decided to delete it so here is case b of the menu instead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
case 'b':
            {
                int index_1 = findName(aList, actual_no);
                cout << "Name 1: " << aList[index_1].name << " found\n";
                
                int index_2 = findName(aList, actual_no);
                cout << "Name 2: " << aList[index_2].name << " found\n";
                
                int decade = getDecadeNo();
                displayDecade(decade);
                
                displayPersonBar(aList, actual_no, index_1, decade);
                displayPersonBar(aList, actual_no, index_2, decade);
                
                break;
            }


I updated the earlier post.

Last edited on
Okay thank you I will work on getting the 3rd part of the menu
closed account (48T7M4Gy)
The third part is a challenge because you need to sort the Names. It's not the only way but I used a selection sort.

http://www.geeksforgeeks.org/selection-sort/
kemort,
Just checking in, still looking at stuff to sort the names. This is what I have for my menu so far
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
55
56
57
void doMenu(Name aList[],  int actual_no,int index)
{

		bool again = true;
		do
		{

			cout << "\ta - Print histogram for a name\n";
			cout << "\tb - Compare two names in a decade\n";
			cout << "\tc - Print top ten names for a decade\n";
			cout << "\td - Quit(write anomalies)\n";

			char userChoice = ' ';
			cout << "\n\tYour selection : ";
			cin >> userChoice;
			cin.get();

			switch (userChoice)
			{
			case 'a':
				displayPersonHistogram(aList, actual_no,index);
				again = true;
				break;
			case 'b':
			  {
			                int index_1 = findName(aList, actual_no);
			                cout << "Name 1: " << aList[index_1].name << " found\n";

			                int index_2 = findName(aList, actual_no);
			                cout << "Name 2: " << aList[index_2].name << " found\n";

			                int decade = getDecadeNo();
			                displayDecade(decade);

			                displayPersonBar(aList, actual_no, index_1, decade);
			                displayPersonBar(aList, actual_no, index_2, decade);



				again=true;
				break;
			  }

			case 'c':
				// do c stuff
				again = true;
				break;
			case 'd':
				// do d stuff
				again = false;
				break;
			default:
				cout << "Wrong choice of character. Must be a, b, c or d\n";
				break;
			}
		} while (again);
	}
This is what I have for selection sort.
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
void selectSort(Name aList[], int aSize)
{

	int pos_min,temp;

	for (int i=0; i < aSize-1; i++)
	{
	    pos_min = i;
		
		for (int j=i+1; j < aSize; j++)
		{

		if (aList[j] < aList[pos_min])
                   pos_min=j;
	
		}
	
            if (pos_min != i)
            {
                 temp = aList[i];
                 aList[i] = aList[pos_min];
                 aList[pos_min] = temp;
            }
	}
}
Last edited on
closed account (48T7M4Gy)
OK, so now you need to incorporate it in your program and test your ideas out on the data.
Pages: 1234