3

I am converting a project written in C++ for windows. Everything is going fine (meaning I clearly see what needs to be changed to make things proper C++) until I hit this, which is my own little routine to find a keyword in along string of keyword=value pairs:

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++ is telling me "Invalid conversion from const char * to char * " (the precise location of the complaint is the argument variable 'search' )

But it would appear that g++ is dyslexic. Because I am actually going the other way. I am passing in a char * to a const char *

(so the conversion is "from char * to const char *" )

The strstr prototype is char * strstr(const char *, const char *)

There is no danger here. Nothing in any const char * is being modified.
Why is it telling me this? What can I do to fix it?

Thanks for any help.

4

5 回答 5

8

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

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

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

在 C++ 中,该函数被一对重载函数替换,标准说:

7. 函数签名strstr(const char*, const char*)应替换为两个声明:
const char* strstr(const char* s1, const char* s2);
char* strstr( char* s1, const char* s2);
两者都应具有与原始声明相同的行为。

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

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

于 2013-10-10T19:48:44.447 回答
3

尽管声明startasconst 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 {
        ...
    }
    ...
}
于 2013-10-10T19:26:02.797 回答
3

错误与stsrtr. 编译器正在抱怨 ' const char *' 返回的转换strstr。你不能把它分配*startchar *

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

const char *start;

或者

string start(strstr(haystack,search));
于 2013-10-10T19:32:14.463 回答
1

它抱怨的转换是 fromstrstr(...)start。将声明更改startconst char* start;

于 2013-10-10T19:19:40.213 回答
0

你可以使用这样的:

start = const_cast<char *>(strstr( haystack, static_cast<const char *>(search) ));
于 2019-09-04T07:11:16.550 回答