我有一个private char str[256];
为此,我有一个显式的构造函数:
explicit myClass(const char *func)
{
strcpy(str,func);
}
我称之为:
myClass obj("example");
当我编译它时,我收到以下警告:
不推荐将字符串常量转换为'char *'
为什么会这样?
答案 0 :(得分:140)
警告:
不推荐将字符串常量转换为'char *'
是因为你在某处(不是在你发布的代码中)做了类似的事情:
void foo(char* str);
foo("hello");
问题是您正在尝试将字符串文字(类型为const char[]
)转换为char*
。
您可以将const char[]
转换为const char*
,因为数组会衰减到指针,但您正在做的是将可变变量设为常量。
这种转换可能允许C兼容,只是给你提到警告。
答案 1 :(得分:81)
正如answer no. 2 by fnieto - Fernando Nieto明确而正确地描述了这个警告是因为您正在代码中的某个地方(而不是在您发布的代码中),如下所示:
void foo(char* str);
foo("hello");
但是,如果您想保持代码免提警告,那么只需对代码进行相应的更改:
void foo(char* str);
foo((char *)"hello");
即,只需将string
常量强制转换为(char *)
。
答案 2 :(得分:30)
有3个解决方案:
解决方案1:
const char *x = "foo bar";
解决方案2:
char *x = (char *)"foo bar";
解决方案3:
char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");
也可以使用数组代替指针,因为数组已经是常量指针。
答案 3 :(得分:3)
实际上,字符串常量文字既不是const char *也不是char *而是char []。它很奇怪,但在c ++规范中写下来;如果修改它,则行为未定义,因为编译器可能将其存储在代码段中。
答案 4 :(得分:1)
我通过在代码的开头添加此宏来解决此问题。或者将其添加到<iostream>
,呵呵。
#define C_TEXT( text ) ((char*)std::string( text ).c_str())
答案 5 :(得分:1)
也许您可以尝试以下方法:
void foo(const char* str)
{
// Do something
}
foo("Hello")
对我有用
答案 6 :(得分:1)
此问题的原因(比其他人解释的char* str = "some string"
问题更难发现)是在使用constexpr
时。
constexpr char* str = "some string";
似乎它的行为类似于const char* str
,因此不会引起警告,因为它发生在char*
之前,但它的行为却像char* const str
。
常量指针和指向常量的指针。 const char* str
和char* const str
之间的区别可以解释如下。
const char* str
:声明str为指向const char的指针。这意味着该指针指向的数据是恒定的。可以修改指针,但是任何试图修改数据的尝试都会引发编译错误。
str++ ;
:有效。我们正在修改指针,而不是指向的数据。*str = 'a';
:无效。我们正在尝试修改所指向的数据。char* const str
:声明str为指向char的const指针。这意味着该点现在是恒定的,但是所指向的数据也不是恒定的。指针不能被修改,但是我们可以使用指针来修改数据。
str++ ;
:无效。我们正在尝试修改指针变量,它是一个常量。*str = 'a';
:有效。我们正在尝试修改所指向的数据。在我们的情况下,这不会导致编译错误,但会导致 运行时错误 ,因为该字符串很可能会进入已编译二进制文件的只读部分。如果我们已经动态分配了内存,那么该语句就有意义。 char* const str = new char[5];
。const char* const str
:声明str为指向const char的const指针。在这种情况下,我们既不能修改指针,也不能修改指向的数据。
str++ ;
:无效。我们正在尝试修改指针变量,它是一个常量。*str = 'a';
:无效。我们正在尝试修改此指针指向的数据,该数据也是恒定的。在我的情况下,问题是我期望constexpr char* str
的行为像const char* str
,而不是char* const str
,因为从视觉上看,它更接近前者。
此外,为constexpr char* str = "some string"
生成的警告与char* str = "some string"
略有不同。
constexpr char* str = "some string"
的编译器警告:ISO C++11 does not allow conversion from string literal to 'char *const'
char* str = "some string"
的编译器警告:ISO C++11 does not allow conversion from string literal to 'char *'
。您可以使用C gibberish ↔ English converter将C
声明转换为易于理解的英语语句,反之亦然。这是仅C
的工具,因此将不支持C++
专有的功能(例如constexpr)。
答案 7 :(得分:0)
我也遇到了同样的问题。我简单的做法就是添加const char *而不是char *。问题解决了。正如其他人在上面提到的,这是一个兼容的错误。 C将字符串视为char数组,而C ++将它们视为const char数组。
答案 8 :(得分:0)
为了它的价值,我发现这个简单的包装类有助于将C ++字符串转换为char *
:
class StringWrapper {
std::vector<char> vec;
public:
StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
}
char *getChars() {
return &vec[0];
}
};
答案 9 :(得分:-1)
下面说明了解决方案,将字符串分配给变量指向常量char数组的指针(字符串是指向常量char数组的常量指针 - 加上长度信息):
#include <iostream>
void Swap(const char * & left, const char * & right) {
const char *const temp = left;
left = right;
right = temp;
}
int main() {
const char * x = "Hello"; // These works because you are making a variable
const char * y = "World"; // pointer to a constant string
std::cout << "x = " << x << ", y = " << y << '\n';
Swap(x, y);
std::cout << "x = " << x << ", y = " << y << '\n';
}