Code validation (toupper) within an array

First post be gentle.

I have two arrays I need to validate. I need to either check if the first letter is capitalized or just change each first letter to capital.

with a normal string lets say s1 I believe you do this by s1[0] = toupper(s1[0]);

How can you do this within a loop with arrays. Here is where I am at.

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
     for(int i = 0; i < numberOfRecords; i++){

        cout << "Enter the first and last name of student #" << i+1 << endl;
        cin >> firstName[i] >> lastName[i];

    for(int i = 0; i < numberOfRecords; i++){

        cout << "Enter the first and last name of student #" << i+1 << endl;
        cin >> firstName[i] >> lastName[i];

            for(int i = 0; i < numberOfRecords; i++){

        cout << "Enter the first and last name of student #" << i+1 << endl;
        cin >> firstName[i] >> lastName[i];

        firstName[i] = toupper(firstName[i]);//Problem is this line
        lastName[i] = toupper(lastName[i]); //This one as well

        cout << "\nEnter GPA of student #" << i+1 << endl;
        cin >> gpa[i];

        if(gpa[i] < 0 || gpa[i] > 4.00){
            cout << "Error: Re-Enter GPA ";
            cin >> gpa[i];
        }//Ends for loop



Last edited on
Please check your program, each block of code seems to be repeated upto three times.
Anyways, for this specific problem
 I need to either check if the first letter is capitalized or just change each first letter to capital.
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <cctype>
#include <vector>
#include <locale>

int main()
{
    std::vector<std::string> myStringVec {"hello", "world", "this", "is", "C++"};
    std::locale loc{};//for locale-specific version of toupper()
    //http://www.cplusplus.com/reference/locale/toupper/
    for (auto& elem : myStringVec)
    {
        elem = (isupper(elem[0]))? elem : toupper(elem[0], loc) + elem.substr(1);
        //ternary operator: https://www.tutorialspoint.com/cplusplus/cpp_conditional_operator.htm
        //std::basic_string::substr(): http://en.cppreference.com/w/cpp/string/basic_string/substr
        std::cout << elem << ", ";
    }
}

relevant links are in the program, shout if anything's unclear
Thank you I have some research to do, I have not run across any vectors yet or isupper. Thank you for the links to help me get this going. I greatly appreciate it.
shout if anything's unclear

Why are you even bothering to call isupper()? Why not just call toupper() on the first character of the string, after all toupper() will only change lower case letters to upper case it leaves everything else alone. Then all you would need is elem[0] = toupper(elem[0], loc);, no ternary operator, no substr().

In terms of checking the logic at each step, I'm not so sure that's a good idea. Sure in this case there might not performance differences but say we go ahead directly without any checks and now instead of a simple toupper() the program has to commit expensive resources in the alternative scenario. So its better to try and encourage good practices, specially for learners like OP (and moi!)
In terms of checking the logic at each step, I'm not so sure that's a good idea.

What logic? The stated objective is:
I need to either check if the first letter is capitalized or just change each first letter to capital.

So,IMO, your code is using a bunch of extra steps that are not required, with the added benefit of obscuring what you're actually doing. In this case, again IMO, just "converting" the first character to upper case is really the cleanest way to go, and the best practice for this particular assignment.
Hello jlb,

Thank you for the response, I think your way seems to best. So for my program above would this work out with the array? Such as.

firstName[0] = toupper(firstName[0], loc) ? Ill give it a shot
Oh shoot, toupper I believe only works with char type.
In this case, again IMO, just "converting" the first character to upper case is really the cleanest way to go, and the best practice for this particular assignment.

So given a choice b/w checking if something is necessary and only then doing it vs going ahead and doing it anyway without any checks I'd always prefer to check first as a discipline. You are welcome to do whatever you deem best of course
As regards ..
obscuring what you're actually doing.
, the reply from the OP is pretty clear:
Thank you for the links to help me get this going. I greatly appreciate it.
Last edited on
Oh shoot, toupper I believe only works with char type.

the correct way to do this was in my program, shortcuts are not always good ;)). Anyways if you want to toupper straightaway without checks, this is what you need to do:
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>
#include <cctype>
#include <locale>

int main()
{
    std::string firstName = "john";
    std::locale loc{};
    firstName = toupper(firstName[0], loc) + firstName.substr(1);
    std::cout << firstName << "\n";
}



toupper I believe only works with char type.

That is correct.

1
2
      firstName[i] = toupper(firstName[i]);//Problem is this line
        lastName[i] = toupper(lastName[i]); //This one as well 


Since it appears that firstName is a vector or array of string to convert the the first character you would do something like: firstName[i][0] = toupper(firstName[i][0]);



Using a locale here is probably overkill.

So given a choice b/w checking if something is necessary and only then doing it vs going ahead and doing it anyway without any checks I'd always prefer to check first as a discipline.

Seems like checking with the C version of the function while using a locale is counter productive.

As jlb notes, toupper already provides the functionality of "checking," so the effect is accomplished in either case, however in the code provided by gunnerfunner a redundant check is done which may be a pessimization, although I doubt performance is critical here.

For my money, the code is more readable without the check.

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

void capitalize(std::string& s) { if ( !s.empty() ) s[0] = std::toupper(s[0]); }

int main()
{
    auto strings = std::vector<std::string> { "hello", "world", "this", "is", "C++"};

    for (auto& str : strings) capitalize(str);

    for (const auto& str: strings) std::cout << str << '\n' ;
}

Great thank you all, I am going to give this another whirl as to toupper wit does not seem to be working with a string or is it ok since I am narrowing it down to one letter.

Here is the entire program so far, maybe that will clarify a few things.

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
#include <iostream>
#include <string>
#include <iomanip>
#include <cctype>

using namespace std;

int main()
{
    static const int numberOfRecords = 10;
    string firstName[numberOfRecords];
    string lastName[numberOfRecords];
    float gpa[numberOfRecords];

    cout << "Welcome to Student Record's Information" << endl;

    cout << "Please Enter Student details.\n";
    for(int i = 0; i < numberOfRecords; i++){

        cout << "Enter the first and last name of student #" << i+1 << endl;
        cin >> firstName[i] >> lastName[i];
        
        cout << "\nEnter GPA of student #" << i+1 << endl;
        cin >> gpa[i];

        if(gpa[i] < 0 || gpa[i] > 4.00){
            cout << "Error: Re-Enter GPA ";
            cin >> gpa[i];
        }


    }//End of for loop

    cout << "Name (Last, First)" << setw(15) << "GPA\n"
         << "-------------------------\n";
    cout << fixed << showpoint << setprecision(2);
    for(int j = 0; j < numberOfRecords; j++){
        cout << lastName[j] << " , " << firstName[j] << setw(15) << gpa[j]
             << endl;
    }//End of for loop

}//Ends main.


closed account (48T7M4Gy)
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
/*
 1) I need to either check if the first letter is capitalized
 or
 2) just change each first letter to capital.
 
 with a normal string lets say s1
 I believe you do this by s1[0] = toupper(s1[0]);
 */

#include <iostream>
#include <string>

int main(){
    
    std::string an_array_of_strings[]{"first", "Second", "third"};
    size_t no_strings = sizeof(an_array_of_strings)/sizeof(std::string);
    
    
    // 1) CHECK IF 1st CHARACTER IS UPPER CASE
    for(size_t i = 0; i < no_strings; ++i){
        std::cout << an_array_of_strings[i] << " - ";
        if( isupper(an_array_of_strings[i][0]) )
            std::cout << "1st character is upper case\n";
        else
            std::cout << "1st character is not upper case\n";
    }
    
    
    
    // 2) CHANGE 1st CHARACTER TO UPPERCASE
    for(size_t i = 0; i < no_strings; ++i){
        an_array_of_strings[i][0] = toupper(an_array_of_strings[i][0]);
        std::cout << an_array_of_strings[i] << '\n';
    }
    
    return 0;
}


first - 1st character is not upper case
Second - 1st character is upper case
third - 1st character is not upper case
First
Second
Third
Program ended with exit code: 0
Last edited on
Thank you kemort.

I notice everybody not using "using namespace std;" is that standard practice?

closed account (48T7M4Gy)
There's a story to it, best see http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice

It's good to use using etc for study purposes to avoid all the std::'s (no-pun intended) but preferably not as time moves on for robust and lengthy/complex code.

Cheers
jlb-

Thank you this program now works correctly. If anybody else has this problem I'll post the entire program.
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 main()
{
    static const int numberOfRecords = 10;
    string firstName[numberOfRecords];
    string lastName[numberOfRecords];
    float gpa[numberOfRecords];


    cout << "Welcome to Student Record's Information" << endl;
    cout << "Please Enter Student details.\n";

    for(int i = 0; i < numberOfRecords; i++){

        cout << "Enter the first and last name of student #" << i+1 << endl;
        cin >> firstName[i] >> lastName[i];

        cout << "\nEnter GPA of student #" << i+1 << endl;
        cin >> gpa[i];

        if(gpa[i] < 0 || gpa[i] > 4.00){
            cout << "Error: Re-Enter GPA ";
            cin >> gpa[i];
        	}//Ends  if validation check
       }//End input for loop

        for(size_t i = 0; i < numberOfRecords; ++i){
             firstName[i][0] = toupper(firstName[i][0]);
             lastName[i][0] = toupper(lastName[i][0]);
        }//Ends toupper for loop

    cout << "Name (Last, First)" << setw(15) << "GPA\n"
         << "-------------------------\n";
    cout << fixed << showpoint << setprecision(2);
    for(int j = 0; j < numberOfRecords; j++){
        cout << lastName[j] << " , " << firstName[j] << setw(15) << gpa[j]
             << endl;
    }//End of for loop
}//Ends main. 
Topic archived. No new replies allowed.