JATX99
JATX99

Reputation: 17

Capitalization of a String

I'm extremely new to C++ and I have an assignment to first format a name provided via the user, and then ensure it has proper capitalization (First letter capital, rest lowercase).

I feel like I have the function correct, but the function involves an array and the code I have written does not seem to allow a string to be initialized to the array.

The output of the first stretch of code is then input into the capitalize function and that is where I am running into an error.

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

void capitalize(char str[]);

int main()
{
    //inputs user name in the format first, middle and last name
    string name;
    cout << "Enter your name in the order of first middle last: ";
    getline(cin, name, '\n');

    //string variables to extract the first. middle and last names
    //from the input
    string first, last, middle, subOutput;



    // finds the poisiton of first space
    int firstblank = name.find(' ', 0);


    // taken as first name until the first space
    first = name.substr(0, firstblank);


    // finds second space
    int secondblank = name.find(' ', firstblank + 1);


    // if second space is not found means no middle name in the input
    if (secondblank == -1)
    {
        // taken the remaining string as last name
        last = name.substr(firstblank + 1);
        // prepares name as desired output
        subOutput = last + ", " + first;
    }
    else
    {
        // gets middle name from firstspace to second space
        middle = name.substr(firstblank + 1, secondblank - firstblank - 1);
        // gets last name
        last = name.substr(secondblank + 1);
        //prepares output
        subOutput = last + ", " + first + " " + middle.at(0) + ".";
    }

    char O[] = subOutput;
    capitalize(O);
    cout << O << endl;


    //displays output
    //cout << O << endl;

    return 0;
}

void capitalize(char str[]) {
    if (strlen(str) == 0) {
        return;
    }
    str[0] = toupper(str[0]);
    for (int i = 1; i < strlen(str); i++)
    {
        str[1] = tolower(str[i]);
    }
}

Might be a very basic fix but like I said, I am very new to coding/C++ so any help is greatly appreciated!

EDIT: I actually revised my code and I believe I have some of the solution, however there is a bug that I am unsure about. New Code:

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

const int CAPACITY = 1000;


void capitalize(string& str);


int main()
{
    //inputs user name in the format first, middle and last name
    //string variables to extract the first. middle and last names
    string name, first, last, middle, subOutput, Output;
    cout << "Enter your name in the order of first middle last: ";
    getline(cin, name, '\n');


    //from the input




    // finds the poisiton of first space
    int firstblank = name.find(' ', 0);


    // taken as first name until the first space
    first = name.substr(0, firstblank);


    // finds second space
    int secondblank = name.find(' ', firstblank + 1);


    // if second space is not found means no middle name in the input
    if (secondblank == -1)
    {
        // taken the remaining string as last name
        last = name.substr(firstblank + 1);
        // prepares name as desired output
        subOutput = last + ", " + first;
    }
    else
    {
        // gets middle name from firstspace to second space
        middle = name.substr(firstblank + 1, secondblank - firstblank - 1);
        // gets last name
        last = name.substr(secondblank + 1);
        //prepares output
        subOutput = last + ", " + first + " " + middle.at(0) + ".";
    }


    capitalize(subOutput);
    Output = subOutput;
    cout << Output << endl;



    return 0;
}



void capitalize(string& str) {
    if (str.length() == 0) {
        return;
    }
    str[0] = toupper(str[0]);
    for (int i = 1; i < str.length(); i++)
    {
        str[i] = tolower(str[i]);
    }
}

The code compiles and formats properly, however when capitalizing, it only properly capitalizes the last name properly. I am not sure how I can get it to capitalize everything though. Like I said, any help is greatly appreciated!

Upvotes: 0

Views: 3952

Answers (3)

user12347224
user12347224

Reputation:

Use to std::toupper(string[0]) to capitalise the first character. It's builtin function.

Upvotes: 3

Nikhil Badyal
Nikhil Badyal

Reputation: 1697

When you are in c++. Why C-Styled char array. Library string has so m inbuilt function try them. Try this instead. C style arrays are often error-prone. Try to use C++ functions and libraries.

int main()
{
string s;
getline(cin,s);
decltype(s.size()) i = 0;
do{
if(i==0 || isspace(s[i-1]))
{
    s[i] = toupper(s[i]);
}
else{
    s[i] = tolower(s[i]);
    }

++i;
}while(i!= s.size());
cout<<s;
return 0;}

comment if you found it hard to understand.

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84579

You are already using many of the std::basic_string functions, why not simply use the .begin() and .end() iterators and iterate over each character in the string keeping track of the last (previous) character seen and if the last character was whitespace (or a '.' indicating an initial), capitalize the current character, otherwise set to lowercase?

It is actually shorter and simpler. All of the std::basic_string functions are listed. All you need do is:

...
#include <cctype>

/* convert string to Titlecase */
void strtotitle (std::string& name)
{
    char last = ' ';    /* initialize last as whitespace */

    for (std::string::iterator i = name.begin(); i != name.end(); i++) {
        if (isspace(last) || last == '.')
            *i = toupper(*i);   /* convert 1st in word toupper */
        else
            *i = tolower(*i);   /* convert remaining tolower */

        last = *i;              /* save current char as last */
    }
}

Adding a short main() to take the users input you could do:

#include <iostream>
#include <string>
#include <cctype>

/* convert string to Titlecase */
void strtotitle (std::string& name)
{
    char last = ' ';    /* initialize last as whitespace */

    for (std::string::iterator i = name.begin(); i != name.end(); i++) {
        if (isspace(last) || last == '.')
            *i = toupper(*i);   /* convert 1st in word toupper */
        else
            *i = tolower(*i);   /* convert remaining tolower */

        last = *i;              /* save current char as last */
    }
}

int main (void) {

    std::string name {};

    std::cout << "enter name: ";
    if (!getline (std::cin, name)) {
        std::cerr << "(user canceled input)\n";
        return 1;
    }

    strtotitle (name);
    std::cout << "formatted : " << name << "\n";
}

It provides much more flexibility than searching manually for the first or second space, etc..

Example Use/Output

$ ./bin/name2title
enter name: alPHRED c. fudSTER
formatted : Alphred C. Fudster

or

$ ./bin/name2title
enter name: mICKEy mOUSe
formatted : Mickey Mouse

or

$ ./bin/name2title
enter name: m.m. disNey
formatted : M.M. Disney

You can also easily add an additional function to trim leading and trailing whitespace and compress multiple included whitespace to a single space allowing you to fully format even the strangest input.

Look things over and let me know if you have further questions.

Upvotes: 1

Related Questions