无法将const char *转换为char *

4

Visual Studio c++ 2005

我在这段代码的最后一行遇到了一个错误。

int Utils::GetLengthDiff ( const char * input, int & num_subst ) 
{
    int num_wide = 0, diff = 0 ; 
    const char * start_ptr = input ; 

    num_subst = 0 ; 
    while ( ( start_ptr = strstr ( start_ptr, enc_start ) ) != NULL ) 
    {
        char * end_ptr = strstr ( start_ptr, enc_end ); // Error

所以我把这一行改成了这个样子,然后它就可以正常工作了。

const char * end_ptr = strstr ( start_ptr, enc_end ); 

我为什么需要将end_ptr也声明为const呢?

非常感谢。

3个回答

13

C++有两个重载版本的这个函数。http://www.cplusplus.com/reference/clibrary/cstring/strstr/

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

由于你的 start_ptrconst char * 类型,C++ 编译器会调用以 const char * 作为第一个参数的版本,该版本也会返回一个 const char *,因此你必须改变你的返回值类型以匹配它。


2
所以为什么我需要将 end_ptr 声明为 const 呢?
与 start_ptr 需要是 const char* 相同的原因:strstr 返回类型为 const char* (= char const*),因为它在一个常量字符串中搜索(你传递给 strstr 的参数也是 const char*)。特别地,这并不是指针是 const,而是它所指向的内存是 const。可以将其视为指向不可变(即常量)字符串的指针。你可以更改它指向的内容,但不能更改字符串中的单个字符。
这与指向可变字符串的不可更改指针不同,即你可以更改单个字符的字符串。

1
假设从strstr返回的值是char*,第一个参数是const char*,就像在C语言中一样。那么你可以这样写:
const char *s = "hello, world";
strstr(s, "hello")[0] = 'j';

代码可以编译和运行(但是会出现未定义的行为),但这种错误是 const 特别设计来避免的。你将一个 const char* 转换成了 char*,没有进行强制类型转换。

C 无法真正解决这个问题:如果 strstr 返回 const char*,那么在输入非 const 的情况下想要修改字符串时,你必须显式地进行非 const 强制类型转换。因为 C++ 具有函数重载功能,它可以(并且确实)堵住漏洞,使两种情况都能正确工作。因此,在 C++ 中,上述代码无法编译,你的示例代码也是如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接