Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将常量字符*存储到字符*?_C++_Char_Constants_Type Conversion - Fatal编程技术网

C++ 如何将常量字符*存储到字符*?

C++ 如何将常量字符*存储到字符*?,c++,char,constants,type-conversion,C++,Char,Constants,Type Conversion,我有一个工作如预期: #define MAX_PARAM_NAME_LEN 32 const char* GetName() { return "Test text"; } int main() { char name[MAX_PARAM_NAME_LEN]; strcpy(name, GetName()); cout << "result: " << name << endl; } 但是我仍然有常量 尝试仅使用

我有一个工作如预期:

#define MAX_PARAM_NAME_LEN 32

const char* GetName()
{
    return "Test text";
}

int main()
{
    char name[MAX_PARAM_NAME_LEN];
    strcpy(name, GetName());    

    cout << "result: " << name << endl;
}
但是我仍然有
常量

尝试仅使用
char*

char* name;
name = GetName();

我得到了从“const char*”到“char*”的无效转换
。这种转换的最佳习惯是什么?

< p> C++中,典型的“滴<代码> const ”是使用<代码> conconsCAST >:

当然,只有当
s
超出范围时,没有保留
name
时,这才有效。如果是这种情况,那么您将拥有某种形式的持久字符串存储层。

返回“测试文本”
如果您使用的函数将
char*
作为输入,并且您有一个
const char*
(例如只读字符串文字),那么您应该向这些函数提供从该
const char*
开始的字符串的深度副本

否则,如果函数试图修改只读字符串,则可能会在运行时出现未定义的行为

你现在拥有的是足够的;假设您不能使用
std::string
。(如果您可以使用
std::string
,并且所有框架函数都采用
const char*
输入,那么我建议您重构代码以使用
std::string
,并将该字符串类上的
c_str()
方法的输出传递给框架函数。)

最后,如果您的一些框架函数需要一个
char*
,那么您可以自己构建一个小的适配器类:

class Adapter
{
public:
    Adapter(const& Adapter) = delete; /*don't try to copy me please*/
    Adapter& operator=(const Adapter& ) = delete; /*don't try to copy me please*/
    Adapter(const char* s) : m_s(::strdup(s))
    {
    }
    ~Adapter() /*free memory on destruction*/
    {
        ::free(m_s); /*use free to release strdup memory*/
    }
    operator char*() /*implicit cast to char* */
    {
        return m_s;
    }
private:
    char* m_s;
};

然后对于函数
voidfoo(char*c)
,可以调用
foo(Adapter(“Hello”/*或任意常量char**/)
foo
可以使用嵌入在匿名临时文件中的
char*
随心所欲!您甚至可以增强该类,将构造函数转换为
char*
,在这种情况下,只获取指针的一个浅拷贝(析构函数不会删除内存)。

这种转换的最佳习惯是在整个代码中使用
std::string
。由于您正在使用的框架将
const char*
作为其输入,因此您始终可以将调用结果传递给您的
std::string

std::string GetName() {
    return "Test text";
}

int main() {
    std::string name = GetName();
    int res = external_framework_function(name.c_str());
    cout << "result: " << res << " for " << name << endl;
}
由于您使用的框架采用
constchar*
,因此您在这里也很好

如果您需要一个非常量指针,则无法复制字符串。您可以创建一个函数来为您执行此操作,但您仍将负责释放从中获得的副本:

char* copy(const char* orig) {
    char *res = new char[strlen(orig)+1];
    strcpy(res, orig);
    return res;
}
...
char *name = copy(GetName());
...
delete[] name;

您可以显式地强制转换它<代码>(char*)getName()
。但你可能不应该。因为
const
位的意思类似于“承诺不改变它”。因此,如果我有一个函数
void foo(const char*string)
我会说:“给我一个指向字符串的指针,我不会改变它。” 如果您声明一个变量
const char*string=“hello”您的意思是,此字符串不应更改。因为你做出了这个承诺,编译器知道,并且可以使你的代码更有效率。这就是为什么:

const char* a = "hello";
const char* b = "hello";
(a==b); //is probably true
您的编译器知道您不会更改
a
b
,因此它使它们指向相同的地址,因此它只需存储一个
“hello”
字符串。如果您现在开始更改
a
b
也会更改,这不是您想要的

长话短说,如果您完全确定您调用的函数不会更改字符串,那么您可以显式地强制转换它。(或者更好,将函数更改为
(const char*)
(如果是您的)。

如果你不确定,你必须复印一份。(就像你已经在使用strcpy()
)。

你想做什么?如果您不想更改字符串,第一个习惯用法为您服务,并且不使用额外的内存;如果您想更改字符串,您需要将其内容复制到其他位置(因此您需要strcpy或类似内容)。是否从
const char*
未定义的行为中删除const?如果我可以问一下,为什么您要建议一些不受欢迎的内容,而不给出其他建议?@Default,因为这是海报想要知道的方法,我也不能确定在这种情况下会不会很糟糕。
.c_str()
是常量<代码>字符*name=s.c_str()不可编译。@默认删除常量不是UB。但是你是对的,
std::string::c_str
将不起作用,因为它返回
const char*
。如果我想将
const char*
内容“复制”到
char*
(因此,不指定固定大小),该怎么办?我不知道那个字符*的大小,因为稍后我会找到另一个字符。哦,等等。我知道我可以使用
char*name
和than
strcpy(name,GetName())也是。基本上,我得到了一个长度不确定的字符串,它可以完成我的任务。这样做正确吗?@paizza No.使用类似于
std::string name=GetName()的东西
然后将
name.c_str()
传递给任何需要
const char*
的框架函数。还可以创建字符串的副本。不过,稍后需要释放内存,所以在C++中使用<代码> STD::String 要容易得多。code>c_str
是一个函数。你为什么建议进行潜在危险的强制转换?从C++字符串文本中获得非const C字符串的唯一正确方法是复制它。任何修改非常量铸造版本的尝试都是无效的。请不要建议(几乎肯定)会导致难以诊断程序行为的方法。
std::string GetName() {
    return "Test text";
}

int main() {
    std::string name = GetName();
    int res = external_framework_function(name.c_str());
    cout << "result: " << res << " for " << name << endl;
}
const char* name = GetName();
char* copy(const char* orig) {
    char *res = new char[strlen(orig)+1];
    strcpy(res, orig);
    return res;
}
...
char *name = copy(GetName());
...
delete[] name;
const char* a = "hello";
const char* b = "hello";
(a==b); //is probably true