The std::string::c_str()
method returns a pointer to const char
data, but your function expects a pointer to non-const char
data. That is why you are getting an error.
You could use const_cast
to cast away the const
(but that is not really advisable):
char *myString = const_cast<char*>(name.c_str());
functoupper(myString);
std::cout << "Hello, " << name << "!\n";
You could use the non-const std::string::operator[]
to access the string's underlying character data (just be careful because prior to C++11, characters were not required to be stored contiguously in memory, but most std::string
implementations did):
functoupper(&name[0]);
std::cout << "Hello, " << name << "!\n";
In C++17 and later, you can use the non-const std::string::data()
method instead:
functoupper(name.data());
std::cout << "Hello, " << name << "!\n";
That being said, heed this warning when using toupper()
:
Like all other functions from <cctype>
, the behavior of std::toupper
is undefined if the argument's value is neither representable as unsigned char
nor equal to EOF
. To use these functions safely with plain char
s (or signed char
s), the argument should first be converted to unsigned char
... Similarly, they should not be directly used with standard algorithms when the iterator's value type is char
or signed char
. Instead, convert the value to unsigned char
first
With that said, try something more like this:
#include <string>
#include <iostream>
#include <cctype>
void functoupper(char *myString)
{
for (int i = 0; myString[i] != '\0'; ++i) {
unsigned char z = static_cast<unsigned char>(myString[i]);
myString[i] = static_cast<char>(std::toupper(z));
}
}
int main() {
std::string name;
std::cout << "Please, enter your full name in small caps: ";
std::getline(std::cin, name);
functoupper(&name[0]); // or name.data()
std::cout << "Hello, " << name << "!\n";
return 0;
}
That being said, you should just pass the entire std::string
as-is into your function instead, and then you can manipulate it as needed, for instance with the std::transform()
algorithm:
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
void functoupper(std::string &myString)
{
std::transform(myString.begin(), myString.end(), myString.begin(),
[](unsigned char ch){ return std::toupper(ch); }
);
}
int main() {
std::string name;
std::cout << "Please, enter your full name in small caps: ";
std::getline(std::cin, name);
functoupper(name);
std::cout << "Hello, " << name << "!\n";
return 0;
}
Alternatively:
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
std::string functoupper(std::string myString)
{
std::transform(myString.begin(), myString.end(), myString.begin(),
[](unsigned char ch){ return std::toupper(ch); }
);
return myString;
}
int main() {
std::string name;
std::cout << "Please, enter your full name in small caps: ";
std::getline(std::cin, name);
std::cout << "Hello, " << functoupper(name) << "!\n";
return 0;
}