将C样式字符串char *传递给函数参数

时间:2019-06-05 16:21:08

标签: c++ function pointers c-strings

我想更改用户传递的字符串中的字符,将其转换为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]。

2 个答案:

答案 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 ...类似地,当以下情况下,不应将它们直接与标准算法一起使用迭代器的值类型为charsigned 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());