G++ strstr 说从常量字符 * 到字符 * 的转换无效

g++ strstr says invalid conversion from const char * to char *

本文关键字:字符 转换 无效 strstr 常量 G++      更新时间:2023-10-16

我正在为 Windows 转换一个用 C++ 编写的项目。 一切都很顺利(这意味着我清楚地看到需要更改哪些内容才能使事情正确C++(,直到我遇到这个,这是我自己的小例程,在关键字=值对的字符串中找到关键字:

bool GetParameter(const char * haystack, const char *needle) {
    char *search, *start;
    int len;
    len = strlen(needle) + 4;     //  make my own copy so I can upper case it...
    search = (char *) calloc(1,len);
    if (search == NULL) return false;
    strcpy(search,needle);
    strupr(search);
    strcat(search,"=");           //  now it is 'KEYWORD='
    start = strstr(haystack,search);  <---- ERROR from compiler

g++ 告诉我"从常量字符 * 到 char * 的无效转换"(投诉的确切位置是参数变量"搜索"(

但看起来g++是阅读障碍。 因为我实际上正在走另一条路。我正在将字符 * 传递给常量字符 *

(所以转换是"从字符 * 到常量字符 *"(

strstr 原型是 char * strstr(const char *, const char *(

这里没有危险。 任何常量字符 * 中的任何内容都没有被修改。
它为什么要告诉我这个?我能做些什么来修复它?

感谢您的任何帮助。

问题的背景是 C 将函数strstr定义为:

char* strstr(const char*, const char*);

这是因为 C 不允许重载函数,因此为了允许您对 const 和非 const 字符串一起使用 strstr,它接受 const 字符串并返回 non-const。 这在 C 已经脆弱的类型系统中引入了一个弱点,因为它从字符串中删除了常量。C 程序员的工作是不要尝试通过从 strstr 返回的指针进行写入,如果您使用不可修改的字符串。

C++,该函数被一对重载函数所取代,标准说:

7. 函数签名strstr(const char*, const char*)应替换为以下两个声明:

const char* strstr(const char* s1, const char* s2);
char* strstr( char* s1, const char* s2); 两者的行为应与原始声明相同。

这是类型安全的,如果你传入一个常量字符串,你会得到一个常量字符串。 您的代码传入 const 字符串,因此 G++ 通过返回 const 字符串来遵循标准。你得到你想要的。

您的代码在 Windows 上编译,因为显然您在 Windows 上使用的标准库不提供重载,仅提供 C 版本。 这允许您传入常量字符串并返回一个非常量字符串。G++ 根据标准要求提供C++版本。 该错误告诉您您正在尝试将 const 返回值转换为非 const char*。解决方案是将返回值分配给const char*,该值是可移植的,可以在任何地方编译。

错误不是关于stsrtr参数。编译器抱怨strstr返回的'const char *'的转换。您不能将其分配给*start这只是char *

您可以尝试以下方法之一:

const char *start;

string start(strstr(haystack,search));
尽管将

start声明为const char*可能就足够了,但对我来说似乎更合适的是改用std::string对象:

#include <string>
#include <cctype>
#include <algorithm>
bool GetParameter(const char * haystack, const char *needle) {
    std::string hstr(haystack), nstr(needle);
    std::transform(nstr.begin(), nstr.end(),nstr.begin(), ::toupper);
    nstr += "=";
    std::size_t found = hstr.find(nstr);
    if (found != std::string::npos) {
        ...                                 // "NEEDLE=" found
    }
    else {
        ...
    }
    ...
}

它抱怨的转换是从strstr(...)start。将start声明更改为const char* start;

你可以这样使用:

start = const_cast<char *>(strstr( haystack, static_cast<const char *>(search) ));