【问题标题】:How to convert const char* to char* in C?如何在 C 中将 const char* 转换为 char*?
【发布时间】:2014-10-22 08:39:34
【问题描述】:

在我的项目中有一个方法只返回一个const char*,而我需要一个char* 字符串,因为API 不接受const char*

知道如何在const char*char* 之间进行转换吗?

【问题讨论】:

  • 请注意,API 的设计方式可能是出于充分考虑。
  • @alk 我在下面说过这就是这种情况: const char* 由objective-C 字符串方法返回[更具体地说是NSString)。这是保存的文件的路径。现在有另一个 C 库的 api 将解析这个文件,它只接受 char* 字符串作为参数。即使我传递了 const char* 字符串,解析也会发生,但我会收到一个我不想看到的警告。
  • 正如其他人指出的那样:正如您永远不知道解析器做了什么(想想strtok() 做了什么)复制返回的数据并传递副本。 strdup()free()是你的朋友。
  • 你能告诉我们它们是哪些函数并链接到它们的文档吗?
  • 而在 C++ 中有const_cast<>()

标签: c pointers const-char


【解决方案1】:

首先,只有在确实有必要时才应该做这些事情 - 例如。使用一些带有char* 参数的旧式API,这些参数没有被修改。如果 API 函数修改了原来为 const 的字符串,那么这是未指定的行为,很可能会崩溃。

使用演员表:

(char*)const_char_ptr

【讨论】:

  • 我认为这个答案鼓励了太多危险的做法。可以通过使有关未定义行为的警告更清晰和更强来改进它。目前我认为许多读者只会阅读前 2 行,而不会注意到重要的警告。
  • 现在首先是警告,然后是答案。
  • 或者至少使用 const_cast 这样编译器也知道。
  • @MultiMat C 中没有 const_cast 这样的东西。
  • 我的 C++ 生锈了,但是当它超出范围时,这不会导致问题吗?
【解决方案2】:

为了安全起见,您不要破坏内容(例如,当这些字符串在您的代码中或更高版本中更改时),或使您的程序崩溃(以防返回的字符串是文字,例如 "hello I'm a literal string" 并且您开始编辑它),复制返回的字符串。

您可以为此使用strdup(),但请阅读small print。或者,如果您的平台上没有,您当然可以创建自己的版本。

【讨论】:

  • Necro 来回答这个问题,你不能更改代码吗:API 通常需要字符串、char* 或 const char*,是的,理论上你可以更改整个 API,但这是很好的信息要知道如何快速转换它
  • @Skathix 你说得对,API 不能经常更改(我认为写错了)。删除了我答案的那一部分。谢谢!
【解决方案3】:

你可以使用strdup函数,其原型如下

char *strdup(const char *s1);

使用示例:

#include <string.h>

char * my_str = strdup("My string literal!");
char * my_other_str = strdup(some_const_str);

或者 strcpy/strncpy 到你的缓冲区

或在可能的情况下重写您的函数以使用const char * 作为参数而不是char *,这样您就可以保留const

【讨论】:

  • strdup 是一个非标准的实现。所以你不应该确定他“可以使用它”
  • 实现缺少的strdup() 只需 15 分钟。
  • @alk 当然。但是,由于 OP 遇到了这样的问题并正在寻求解决方案,对于他“自己实施 strdup”来说,这可能不是解决方案,你知道吗?
  • @Zaibis: if (constptr) {char * p = calloc(strlen(constptr)+1, sizeof(*constptr)); if (!p) fail(); strcpy(p, constptr); my_nonconstptr_func(p); free(p);}
  • @alk 好了,现在我们有了实现。不会改变我的声明中的任何内容。 ;)
【解决方案4】:

指向指针的const 表示“只读”内存位置。而没有const 的是读写内存区域。因此,您“不能”将const(只读位置)转换为普通(读写)位置。

另一种方法是将数据复制到不同的读写位置并将此指针传递给所需的函数。您可以使用strdup() 来执行此操作。

【讨论】:

  • 没错。 const 被指定为表示该值保持不变并且不能进一步修改。
【解决方案5】:

要将const char* 转换为char*,您可以创建如下函数:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* unconstchar(const char* s) {
    if(!s)
      return NULL;
    int i;
    char* res = NULL;
    res = (char*) malloc(strlen(s)+1);
    if(!res){
        fprintf(stderr, "Memory Allocation Failed! Exiting...\n");
        exit(EXIT_FAILURE);
    } else{
        for (i = 0; s[i] != '\0'; i++) {
            res[i] = s[i];
        }
        res[i] = '\0';
        return res;
    }
}

int main() {
    const char* s = "this is bikash";
    char* p = unconstchar(s);
    printf("%s",p);
    free(p);
}

【讨论】:

  • 在这段代码中使用了未初始化的变量res。此代码res[i] = s[i] 是未定义的行为,很可能会崩溃。
  • 更新代码:添加了对 NULL 的检查并可能解决了未定义的行为。
【解决方案6】:

您可以通过 (char *)Identifier_Of_Const_char 进行投射

但是由于api不接受const cahr *可能是有原因的, 您应该只这样做,如果您确定,该函数不会尝试在您转换为非 const 的 const char* 范围内分配任何值。

【讨论】:

  • const char* 由 Objective-C 字符串方法返回[更具体地说是 NSString]。这是已保存文件的路径。现在有另一个 C 库的 api 将解析这个文件,它只接受 char* 字符串作为参数。即使我传递了 const char* 字符串,解析也会发生,但我会收到一个我不想看到的警告。
  • @Morpheus 反正你不自己分析源头是无法确定的。
猜你喜欢
  • 2019-11-11
  • 2020-08-04
  • 2015-04-02
  • 1970-01-01
  • 2013-12-31
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多