【问题标题】:Converting\casting a void pointer to a string将 void 指针转换为字符串
【发布时间】:2019-05-09 17:35:04
【问题描述】:

我将如何做到这一点,因为我不知道我是否可以读取 void 指针,所以我想先将其转换为字符串。这是我在测试时的尝试:

void* test1;
char test2[] = "ha 21";
char test3[50];

test1 = test2;

test3 = test1;

printf("%s", test3);

return 0;

当我尝试创建 test1 = test 2 时也可能是错误的,但这只是为了显示 void 指针中应该包含的内容。我只是想看看如何将包含字符串的 void 指针转换为字符串。

【问题讨论】:

  • test3 = test1; 是非法的,因为test3 是一个数组,不能赋值。
  • @Osiris 可能是这种情况,但是我如何将 void 指针实际转换为字符串,因为我非常卡住
  • 您可以使用strcpymemcpy将字符串的字节复制到test3数组中。

标签: c string void-pointers


【解决方案1】:

When I try to make test1 = test2 is probably wrong as well but that is just to show what should be in the void pointer.

test1 = test2 完全正确。来自 C 标准#6.3.2.3p1

1 指向 void 的指针可以转换为指向任何对象类型的指针或从指向任何对象类型的指针转​​换。指向任何对象类型的指针都可以转换为指向 void 的指针并再次返回;结果应与原始指针比较。

问题出在这句话上:

test3 = test1;

test3 是一个数组,您不能将 test1 分配给 test3,因为在 C 中,数组名称是不可修改的左值。

相反,您应该将test1 的内容复制到test3,然后您可以使用strcpy()

但是strcpy() 不安全,因为它无法知道目标缓冲区有多大,如果目标缓冲区不足以容纳源字符串(包括空终止字符),您最终可能会导致缓冲区溢出.在复制字符串之前,如果您可以确保目标缓冲区足够长以容纳源字符串(包括空终止字符),那么使用strcpy() 将源字符串复制到目标缓冲区完全可以。在您的情况下,由于目标缓冲区大小为50,它足以容纳源字符串"ha 21",您可以安全地使用strcpy()。所以,而不是这个:

test3 = test1;

你应该这样做:

strcpy(test3, test1);

补充:

strncpy() 不是strcpy() 的更安全版本。
在这里阅读why strncpy() is introduced?

但是,您可以使用strncpy() 作为替代方案(大多数开发人员都这样做),因为它可以防止缓冲区溢出,但请记住,如果源长度大于最大值,则不会在目标末尾隐式附加空字符要从源复制的字符数。在源比目标长的情况下,您需要明确处理这种情况。

【讨论】:

    【解决方案2】:

    由于test3 是一个数组类型,它不能被赋值。 在 C 中,您可以将每个指针转换为 void * 并返回(它是隐式转换的)。

    所以一个可能的解决方案是将test3声明为指针:

    void *test1;
    char test2[] = "ha 21";
    char *test3;
    
    test1 = test2;
    test3 = test1;
    
    printf("%s", test3);
    

    或者如果你想复制内存(如 cmets 中所述):

    void *test1;
    char test2[] = "ha 21";
    char test3[50];
    
    test1 = test2;
    strcpy(test3, test1);
    
    printf("%s", test3);
    

    【讨论】:

    • 非常感谢,解决了它
    • 没有线索 - 有时你永远不会知道,除非这个人有诚信发表评论解释 DV(在 SO 上很少而且相差甚远)。这里没有任何问题(您总是可以添加验证等,但从示例中可以清楚地看出test1 所指向的内容将适合第二个示例中的test3,而无需更多)。所以不要太担心一个无法解释的、不经意的 DV ——它们都会被洗掉。 (这并不能阻止他们感到沮丧,但是 DV'er 需要 1 分来投射它,所以它不是免费的——他们曾经是......)
    • @WillA - 过了一段时间后有任何其他答案,请查看:What should I do when someone answers my question?
    • strcpy 绝对没有问题 - 只要您提供 nul-terminated 字符串并确保目标有足够的空间来容纳源。没有对额外空间进行归零(与strncpy 一样,因此大缓冲区没有性能损失)。它与gets提出的问题没有任何关系。
    • @torstenvl:不,strncpy (几乎可以肯定)不是答案。首先,尽管名称具有欺骗性,但它并不是真正的字符串函数。其次,如果目标数组不够大,它会默默地截断数据,而这很少是正确的响应(考虑将"rm -rf $HOME/tmpdir" 截断为"rm -rf $HOME"。更多信息:the-flat-trantor-society.blogspot.com/2012/03/…
    猜你喜欢
    • 2013-03-06
    • 2016-01-12
    • 2021-01-13
    • 1970-01-01
    • 2011-12-12
    • 2013-11-18
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多