[英]Passing C-Style string char * to function argument
我想更改用户传递的字符串中的字符,将其转换为C样式的字符串,并作为参数传递给具有char *参数的函数:
#include <string>
#include <cstring>
#include <iostream>
#include <stdlib.h>
void functoupper(char *myString)
{
int i=0;
char z;
do {
z= myString[i];
myString[i]=toupper(z);
++i;
} while(myString[i]!=0);
}
int main() {
std::string name;
std::cout << "Please, enter your full name in small caps: ";
std::getline (std::cin,name);
const char *myString = name.c_str();
std::cout << "Hello, " << functoupper(myString) << "!\n";
return 0;
}
我收到错误错误消息:在main()中调用函数functoupper(myString)时,从'const char *'到'char *'的无效转换[-fpermissive]。
std::string::c_str()
方法返回一个指向const char
数据的指针,但是您的函数需要一个指向非const 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和更高版本中,可以改用非const std::string::data()
方法:
functoupper(name.data());
std::cout << "Hello, " << name << "!\n";
话虽如此,使用toupper()
时请注意以下警告:
与
<cctype>
所有其他函数一样,如果参数的值既不能表示为unsigned char
也不等于EOF
,则std::toupper
的行为是不确定的。 为了安全地将这些函数与纯char
s(或带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;
}
正如@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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.