Reputation: 17
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
Reputation:
Use to std::toupper(string[0])
to capitalise the first character. It's builtin function.
Upvotes: 3
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
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