我想更改用户传递的字符串中的字符,将其转换为C样式的字符串,并作为参数传递给具有char *参数的函数:
src
src/main
src/main/resources/application.properties
src/main/java
src/main/java/com.trucker
src/main/java/com.trucker/App.java
src/main/java/com.trucker.controller
src/main/java/com.trucker.controller.VehicleController
src/main/java/com.trucker.entity.Vehicle
src/main/java/com.trucker.repository
src/main/java/com.trucker.repository.VehicleRepositoryInterface
src/main/java/com.trucker.service
src/main/java/com.trucker.service.vehicleService
我得到错误错误:在main()中调用函数functoupper(myString)时,从'const char *'到'char *'的无效转换[-fpermissive]。
答案 0 :(得分:3)
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
话虽如此,请尝试以下类似操作:
#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;
}
答案 1 :(得分:2)
正如@Someprogrammerdude和@RemyLebeau所评论的那样,为什么不简单:
std::transform(std::begin(name), std::end(name), std::begin(name),
[](const unsigned char c)
{
return std::toupper(c);
});
但是,如果必须通过char*
进行操作,则需要先复制数据,例如:
char myString* = new char[name.size() + 1];
strcpy(myString, name.c_str());
编辑:感谢@RemyLebeau的有用评论
只需将std::string
改成std::vector
,就可以更好地避免上述所有内存管理问题:
std::vector<char> myVec(std::begin(name), std::end(name));
myVec.push_back(`\0`);
,然后使用以下命令调用您的char*
函数:
functoupper(myVec.data());