Rooke RON
Rooke RON

Reputation: 15

How to capitalize the first letter of each name in an array?

Here is the question:

Create a function that takes an array of names and returns an array where only the first letter of each name is capitalized.

example

capMe(["mavis", "senaida", "letty"]) ➞ ["Mavis", "Senaida", "Letty"]

And the code I wrote to answer this question:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

void capme(vector<string> name)
{
    char ch;
    for(int i = 0; i < name[i].size(); i++)
    {
        putchar(toupper(name[i][0]));
        cout << name[i] << endl;
    }
}

int main()
{

   vector <string> name = {"mavis", "senaida", "letty"};
   capme(name);
   return 0;
}

As you can see, it prints "Mmavis", "Ssenaida", "Lletty", which is wrong. Can you guys help me in answering this question as I don't know how?

Upvotes: 0

Views: 1007

Answers (3)

hackexe
hackexe

Reputation: 33

You are calling putchar() which writes a character to standard output, and in this case is printing the first letter of each string in name as uppercase, then you are writing the entire string to standard output immediately after.

Additionally, your function does not meet the requirements you stated above saying it should return an array where the strings have the first letter capitalized.

What you could do is change the signature of capme() to return a std::vector<std::string>, and perhaps utilize the for_each() function to handle changing the first letter of each string in your vector then return it.

For reference:

#include <vector>
#include <string>
#include <algorithm>
#include <cctype>

std::vector<std::string> capme(std::vector<std::string> name)
{
    std::for_each(name.begin(), name.end(), [](std::string &s) {
        s[0] = toupper(s[0]);
    });
    return name;
}

Or as kesarling suggested, a simple for each loop:

std::vector<std::string> capme(std::vector<std::string> name)
{
    for (auto& s : name) {
        s[0] = toupper(s[0]);
    }
    return name;
}

Upvotes: 0

prehistoricpenguin
prehistoricpenguin

Reputation: 6326

To change the input argument, we have two choice: make the argument mutable reference, or add a return type, here I choose the first one.

putchar can be used to print only one character, it recommended to use cout to print a string, possible solutions:

  1. with traditional loop: capme

  2. with range for-loop since c++11 : capme2

  3. with stl algorithm transform: capme3

Don't forget to check if the string element is empty, or you may crash while accessing the first character.

To obey the single-responsibility principle (SRP), it's better to print the string vector out of the capme function.

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

void capme(vector<string>& name) {
  for (int i = 0; i < name[i].size(); i++) {
    if (name[i].empty()) continue;
    name[i][0] = toupper(name[i][0]);
  }
}

void capme2(vector<string>& names) {
  for (auto& name : names) {
    if (name.empty()) continue;
    name[0] = toupper(name[0]);
  }
}

void capme3(vector<string>& names) {
  std::transform(names.begin(), names.end(), names.begin(), [](auto& s) {
    return s.empty() ? s : (s[0] = toupper(s[0]), s);
  });
}

Online demo

Upvotes: 1

kesarling
kesarling

Reputation: 2238

You have used the wrong function. What you need is a replacement and not a prepend. Try using std::string::operator[] to access the first element of the words in the vector. This is how I would write this code:

std::vector<string> capitaliseInitLetter(std::vector<string> vec) {
    for (auto& word : vec) {
        word[0] -= 32; //add a check to see if the letter is already capital
    }
    return vec;
}

The above code is just an example which assumes that the input is valid. You'll have to add checks and exception handling for invalid inputs on your own. (Hint: Take a look at @prehistoricpenguin's answer)

Upvotes: 0

Related Questions