【问题标题】:Convert C++ byte array to a C string将 C++ 字节数组转换为 C 字符串
【发布时间】:2019-12-15 09:01:06
【问题描述】:

我正在尝试将字节数组转换为 C 中的字符串,但我不太明白。

我有一个在 C++ 中适用于我的示例,但我需要将其转换为 C。

C++ 代码如下:

#include <iostream>
#include <string>

typedef unsigned char BYTE;

int main(int argc, char *argv[])
{
  BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
  std::string s(reinterpret_cast<char*>(byteArray), sizeof(byteArray));
  std::cout << s << std::endl;

  return EXIT_SUCCESS;
}

谁能指出我正确的方向?

【问题讨论】:

  • String 一个以'\0'结尾的字节数组。所以,是的,你也需要它的大小来容纳它。
  • 你不是缺少一个空终止符吗?
  • @LeeDanielCrocker 请真正阅读这个问题,而不仅仅是代码。 OP 有 C++ 代码;但他们想知道如何在 C 中做同样的事情。
  • @Konrad 好的,很抱歉造成混乱。我看错了。
  • 我将添加两个标签。任何不同意的人请在元here 上接受它,而不是通过编辑破坏这个问题。

标签: c++ c arrays string


【解决方案1】:

C 中的字符串 以零结尾的字节数组。因此,您需要做的就是将数组复制到一个新的缓冲区中,该缓冲区有足够的空间容纳尾随零字节:

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

typedef unsigned char BYTE;

int main() {
    BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
    char str[(sizeof byteArray) + 1];
    memcpy(str, byteArray, sizeof byteArray);
    str[sizeof byteArray] = 0; // Null termination.
    printf("%s\n", str);
}

【讨论】:

  • @πάνταῥεῖ 每次都会更改我对 OP 的标签。第一行声明代码是 C++ 中的,但我想要它在 C 中。这是一种享受,并且会在能够接受时接受
  • @DanJamesPalmer 请不要玩游戏,即使是无意的。如果您想要 C,请向我们展示 C 代码。不要使用 C++ 作为演示 C 代码的一种方式。 这是两种不同的语言,具有适合每种语言的不同工具和方法。 C++ 可以使用 C 代码并不是混淆两者的理由。
  • @tadman 这是不公平的指控。标签说 C,标题说 C,问题主体说 C。我们(包括我在内!)只是看到 C++ 代码就跳了起来,忽略了标签和标题中提到的 C,比如巴甫洛夫狗(因为我们'已经习惯于在两种语言之间进行错误标记),但这个问题清楚地表明了为什么要包含 C++ 代码,以及它是如何相关和合法的。
  • @KonradRudolph 存在 C++ 代码,这是一个红鲱鱼,这真的不需要。我的观点是,如果问题中有 C++ 代码,根据定义,它是一个 C++ 问题,应该这样标记。如果您只想要 C 和 C,甚至不要去那里,只需使用 C 和交易。
【解决方案2】:

C 字符串是空终止符,因此对于空终止符,字符串的大小将是数组的大小加一。然后你可以使用memcpy() 复制字符串,像这样:

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

typedef unsigned char BYTE;

int main(void)
{
  BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };

  // +1 for the NULL terminator
  char str[sizeof(byteArray) + 1];
  // Copy contents
  memcpy(str, byteArray, sizeof(byteArray));
  // Append NULL terminator
  str[sizeof(byteArray)] = '\0';

  printf("%s\n", str);    
  return EXIT_SUCCESS;
}

输出:

你好

Run it online

【讨论】:

  • 你错过了'\0'
  • 看起来很慢。为什么在复制之前清除整个缓冲区? strcpy() 也不正确,因为源不是空终止的。
  • @AlexisWilke 对,我可以memcpy(),这也不需要演员表。确实不需要清除,我可以附加 NULL 终止符,对吧?
【解决方案3】:

这是一个演示程序,展示了它是如何完成的。

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

typedef unsigned char BYTE;

int main(void) 
{
    BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
    char s[sizeof( byteArray ) + sizeof( ( char )'\0' )] = { '\0' };

    memcpy( s, byteArray, sizeof( byteArray ) );

    puts( s );

    return 0;
}

程序输出是

Hello

注意字符数组是零初始化的。否则,在调用 memcpy 之后,您必须“手动”附加终止零。

s[sizeof( s ) - 1] = '\0';

s[sizeof( byteArray )] = '\0';

当字符数组的大小远大于 byteArray 的大小时,应使用最后一个变体。

【讨论】:

  • 只有当字符串真的很大时,.. = { '\0' } 才是真正的浪费。
  • @AlexisWilke 所以正如我所说,可以手动附加终止零。:)
  • @gsamaras 不,我不需要。但是这个变种已经在我的回答中显示了。:)
  • 我以为你的意思是sbyteArray,这是错误的,现在没关系,误读了,συγγνώμη! :)
猜你喜欢
  • 1970-01-01
  • 2012-02-01
  • 2018-01-26
  • 2017-12-11
  • 2018-03-20
  • 1970-01-01
  • 2021-12-02
  • 2014-11-03
  • 1970-01-01
相关资源
最近更新 更多