错误 C2440:“=”:无法从“const char *”转换为“char *”

Posted

技术标签:

【中文标题】错误 C2440:“=”:无法从“const char *”转换为“char *”【英文标题】:error C2440: '=' : cannot convert from 'const char *' to 'char *' 【发布时间】:2013-05-01 16:14:00 【问题描述】:

我在这里花了很多时间寻求帮助,以解决显然是常见错误的问题,但我所看到的似乎都不适合我的情况。

我正在将一个用 Visual Studio 6 C++ 编写的旧外源程序迁移到 Visual Studio 2012,幸运的是我不是 C++ 程序员(只是一个低级的 VB 和 C# 开发人员)。迁移向导和 Internet 在帮助我查找和更正向导无法处理的代码方面提供了很大帮助。

在这个代码块中,我认为它只不过是创建一个目录

int CreateAllDirectories(const char* pszDir)

char*   pszLastSlash;
char    cTmp;


if( _access( pszDir, 0 ) != -1 ) 
    // it already exists
    return 0;


pszLastSlash = strrchr( pszDir, '\\' );
if ( pszLastSlash ) 
    cTmp = *pszLastSlash;
    *pszLastSlash = '\0';

    // try again with one less dir
    CreateAllDirectories( pszDir ); 

    *pszLastSlash = cTmp;


if ( _mkdir( pszDir ) == -1 ) 
    return -1;


return 0;

将 strrchr( pszDir, '\' ) 的结果分配给变量 pszLastSlash 时会产生错误。从这段代码的其余部分看起来像 pszLastSlash = strrchr( pszDir, '\' );是一个有效的表达式。

在我看来是双反斜杠和转义序列的问题。

【问题讨论】:

【参考方案1】:

也许在这一行……​​

pszLastSlash = strrchr( pszDir, '\\' );

pszLastSlash 不是常数,但 pszDir 是常数。 strrchr() 有两个定义(见http://www.cplusplus.com/reference/cstring/strchr/)...

const char * strchr ( const char * str, int character );
      char * strchr (       char * str, int character );

因为你输入了一个常量 char *,它会尝试使用返回一个 const char* 的 def,但是你将它分配给一个非 const char*。我认为这就是产生错误的原因。

因为pszDir 是const,所以返回给您的指针是const,因为您不应该修改pszDir 指向的内存区域。

如果你自己分配了pszDir,并且你知道修改是安全,你可以放松你在函数def中的const约束吗?即,

int CreateAllDirectories(char* pszDir)

但是,只有pszDir 是您拥有并且可以修改的字符串:)

我刚刚在 C++ 参考页面中注意到...

In C, this function is only declared as:
    char * strchr ( const char *, int ); 

因此,如果您以前使用过 C,那么这将解释您现在看到错误的原因。

【讨论】:

是的,这就是答案。您也可以建议将const char* pszDir 更改为char* pszDir,因为它可以在函数内部进行更改。或者复制一份。 所以您是建议他尝试更改CreateAllDirectories() 上的pszDir 参数以获得缓解? @Soon:感谢您的评论,已更新。我认为他应该只更改 pszDir 的 const'ness,前提是他知道写信是安全的...... @Jimbo:他已经假设了,因为他正在给它写信。 @Ben,说得好,是的。鉴于 func def 是 const,这意味着他也认为他不会,所以有一些混乱。我认为值得仔细检查,尽管正如你所说,他很可能可以写信给它并且确实想要。【参考方案2】:

从这一行开始

*pszLastSlash = '\0';

正在修改传递给你的函数的缓冲区,你不能向你的调用者保证你不会修改缓冲区。因此

int CreateAllDirectories(char* pszDir);

是正确的签名

【讨论】:

【参考方案3】:

你可以试试把new放在中间

pszLastSlash = strrchr( pszDir, '\' );

原来如此

:pszLastSlash = new strrchr( pszDir, '\' );

【讨论】:

以上是关于错误 C2440:“=”:无法从“const char *”转换为“char *”的主要内容,如果未能解决你的问题,请参考以下文章

错误 C2440:“正在初始化”:无法从“const int”转换为“int *”

vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决

vs2017 :C2440 错误,无法从 const char[] 转换为 char*问题解决

error C2440: “=”: 无法从“const char [18]”转换为“LPCWSTR”

error C2440: “=”: 无法从“const char [18]”转换为“LPCWSTR”

error C2440: “=”: 无法从“const wchar_t [4]”转换为“LPWSTR”