How to Capitalize a String for Comparison

I have a program where the user types in a name and the program reads a file with a list of names and compares it to the name the user inputted. If the name is found it displays the name and the rank of popularity in boy and girl names. The program runs fine, but I wanted to capitalize the first letter of the and have the rest be lowercase, so the program can compare them correctly. Here is my code and the function prompt is the one that asks for the name. I need to use the method toUpper to do this and I have tried and looked for a solution but I have just seen arrays and the output of the string where as I need the string to be compared to something else.
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
58
59
60
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cctype>
using namespace std;
void prompt(string& name);
void nameTester(ifstream& inStream, string name, string male, string female, int placement, int& malePlacement, int& femalePlacement, bool& isMale, bool& isFemale);
void output(string name, int malePlacement, int femalePlacement, bool isMale, bool isFemale);
int main()
{
    ifstream inStream;
    bool isMale = false, isFemale = false;
    string name, female, male;
    int placement, malePlacement, femalePlacement;
    prompt(name);
    nameTester(inStream, name, male, female, placement, malePlacement, femalePlacement, isMale, isFemale);
    output(name, malePlacement, femalePlacement, isMale, isFemale);
}
void prompt(string& name)
{
    cout << "Enter a name and this program will check if the name is ranked in the top 1,000 most popular names: ";
    cin >> name;
}
void nameTester(ifstream& inStream, string name, string male, string female, int placement, int& malePlacement, int& femalePlacement, bool& isMale, bool& isFemale)
{
    inStream.open("babynames2004.txt");
    if (inStream.fail())
    {
        cout << "There was an error opening the file. The program will now close.\n";
        exit(1);
    }
    while (! inStream.eof())
    {
        inStream >> placement >> male >> female;
        if (name == male)
        {
            isMale = true;
            malePlacement = placement;
        }
        if (name == female)
        {
            isFemale = true;
            femalePlacement = placement;
        }
    }
    inStream.close();
}
void output(string name, int malePlacement, int femalePlacement, bool isMale, bool isFemale)
{
    if (isMale == true)
        cout << name << " is ranked " << malePlacement << " in popularity among boys\n";
    else
        cout << name << " is not ranked among the top 1000 boy names\n";
    if (isFemale == true)
        cout << name << " is ranked " << femalePlacement << " in popularity among girls\n";
    else
        cout << name << " is not ranked among the top 1000 girl names\n";
}
You can do it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

string ucfirst(const string& input)
{
  string output(input);
  if (!input.empty())
    output[0] = static_cast<char>(toupper(input[0]));

  return output;
}

int main()
{
  string name;
  cout << "Enter a name: ";
  getline(cin, name);
  cout << "Name with first char uppercase: " << ucfirst(name) << "\n\n";
  system("pause");
  return 0;
}

The use of std::toupper() is like this:

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

std::string cap_first(const std::string &);

int main()
{
    std::string str;

    // modifying original string

    std::cout << "Enter word: " << std::flush;
    std::cin >> str;
    str[0] = std::toupper(str[0]);
    std::cout << str << "\n\n";

    // not modifying original string

    std::cout << "Enter word: " << std::flush;
    std::cin >> str;
    std::cout << cap_first(str) << '\n';

    return 0;
}

std::string cap_first(const std::string &str)
{
    std::string temp = str;
    if (!(temp.empty()))
    {
        temp[0] = std::toupper(temp[0]);
    }
    return temp;
}
Last edited on
If the user enters a string like this:
 
cin >> name;

We don't know anything about whether it is all uppercase, all lowercase or a mix of both. A sensible approach is to convert the whole string to lowercase, and the first character to uppercase. It might even be a good idea to do the same with the names read from the file. At least this way, the comparing of values is guaranteed to be consistent.
The code above was just an example.

This could be implemented with a range based for loop which converts the string to lowercase before the first character is converted to uppercase.
Last edited on
There's an overloaded version of toupper() that uses std::locale

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

using namespace std;

int main()
{
    locale loc;
    string name;
    cin >> name;
    name = toupper(name[0], loc) + name.substr(1);
    cout << name;
}
Topic archived. No new replies allowed.