Метод std::string::c_str()
возвращает указатель на данные const char
, но ваша функция ожидает указатель на неконстантные char
данные.Вот почему вы получаете ошибку.
Вы можете использовать const_cast
, чтобы отбросить const
(но это не очень рекомендуется):
char *myString = const_cast<char*>(name.c_str());
functoupper(myString);
std::cout << "Hello, " << name << "!\n";
Вы можете использовать неконстантный std::string::operator[]
для доступа к базовым символьным данным строки (просто будьте осторожны, потому что до C ++ 11 символы не требовались для хранениянепрерывно в памяти, но большинство std::string
реализаций сделали):
functoupper(&name[0]);
std::cout << "Hello, " << name << "!\n";
В C ++ 17 и более поздних версиях вы можете использовать неконстантные std::string::data()
метод вместо:
functoupper(name.data());
std::cout << "Hello, " << name << "!\n";
При этом обратите внимание на это предупреждение при использовании toupper()
:
Как и все другие функции из <cctype>
поведение std::toupper
не определено, если значение аргумента не может быть представлено как unsigned char
или равно EOF
.Чтобы безопасно использовать эти функции с обычными char
с (или signed char
с), аргумент должен быть сначала преобразован в unsigned char
... Аналогично, они не должны напрямую использоваться со стандартными алгоритмами, когда тип значения итератора равен char
или signed char
.Вместо этого преобразуйте значение в unsigned char
first
. С учетом вышесказанного попробуйте что-то более похожее на это:
#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;
}
При этом вы должны просто пропустить std::string
как есть в вашей функции, а затем вы можете манипулировать ею по мере необходимости, например, с помощью алгоритма std::transform()
:
#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;
}
В качестве альтернативы:
#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;
}