【问题标题】:char array to uint8_t arraychar 数组到 uint8_t 数组
【发布时间】:2012-06-06 02:19:18
【问题描述】:

这是我从未擅长的 C/C++ 领域之一。

我的问题是我有一个最终需要包含一些空字符的字符串。将所有内容都视为 char 数组(或字符串)是行不通的,因为当他们找到第一个 null 时,事情往往会崩溃。所以我想,好吧,我会切换到 uint8_t,所以一切都只是一个数字。我可以根据需要移动东西,并在我准备好时将其转换回字符。

我现在的主要问题是:如何将字符串的一部分复制到 uint8_t 缓冲区?

实际上,我想做这样的事情:

std::string s = "abcdefghi";
uint8_t *val = (uint8_t*)malloc(s.length() + 1);
memset(val, 0, s.length() + 1);

// Assume offset is just some number
memcpy(val + offset, s.substr(1, 5).c_str(), 5);

显然,当我尝试此操作时出现错误。在 memcpy 的第一个参数中可能存在某种诡计(我在网上看到 (*(uint8_t*)) 之类的东西,但不知道这意味着什么)。

有什么帮助吗?

当我在这里时,如何轻松地将其转换回 char 数组?只是将 uint8_t 指针静态转换为 char 指针?

非常感谢。

【问题讨论】:

  • std::string 完全能够包含'\0' 字符。除非您使用 C 字符串操作函数或其他仅使用 char*s 且没有长度的 API,否则没有理由必须这样做。无论如何,这些 API 不会对嵌入空值的字符串做正确的事情。
  • 看完你的笔记后,我开始四处张望。 std::string 可能会解决。我将进行一些测试。看起来我很好,只要我远离 c_str。出于好奇,我仍然想知道上述问题的答案。
  • (*(uint8_t*)) 这样的东西通常被强制转换为更抽象的数据类型,然后是一个在那个时候变得合法但以前不合法的强制转换,然后是一个回退.它在转换函数指针时经常使用,例如(DWORD)(*(void**))(void(*)(int))(-ish,有一段时间没有使用它)。仅供参考。 :)
  • "很明显,当我尝试这个时遇到错误"。不要让我们猜测。您收到什么错误消息?
  • 您有多个不正确的基本假设。因此很难回答你的问题。 char 数组完全能够保存 nul 字符,作为 std::string 对象。此外,uint8_t 没有什么比 char 做得更好。请向我们展示您尝试过的方法,我们会告诉您哪里出错了。你能创建一个 10 行的程序来演示你出了什么问题吗?见sscce.org

标签: c++ casting char buffer unsigned


【解决方案1】:

我想,好吧,我会切换到 uint8_t,所以一切都只是一个数字。

这不会让寻找“\0”的算法突然停止,使用字符的算法也不会关注“\0”。用空字符表示结束是 C 字符串的约定,而不是 char 数组。 uint8_t 可能只是 char 的 typedef。

正如 Nicol Bolas 指出的那样,std::string 已经能够存储包含空字符的字符串,而无需特殊处理空字符。

至于你的问题,我不确定你指的是什么错误,因为以下工作正常:

#include <iostream>
#include <string>
#include <cstdint>
#include <cstring>

int main() {
    std::string s = "abcdefghi";
    std::uint8_t *val = (std::uint8_t*)std::malloc(s.length() + 1);
    std::memset(val, 0, s.length() + 1);

    int offset = 2;
    std::memcpy(val + offset, s.substr(1, 5).c_str(), 5);
    std::cout << (val+offset) << '\n';
}

memcpy 行从字符串s 中取出第二个到第六个字符并将它们复制到 val 中。带有 cout 的行然后打印“bcdef”。

当然这是 C++,所以如果你想手动分配一些内存并将其清零,你可以这样做:

std::unique_ptr<uint8_t[]> val(new uint8_t[s.length()+1]());

或使用向量:

std::vector<uint8_t> val(s.length()+1,0);

要从 uint8_t 数组进行转换,您可以(但通常不应该)执行以下操作:

char *c = reinterpret_cast<uint8_t*>(val);

【讨论】:

    【解决方案2】:

    好吧,代码工作正常,它复制了 val 中的子字符串。但是,直到偏移量为止,您的所有位置都会有 0。

    例如对于 offset=2 val 将是 {0, 0, b, c, d, e, f, 0, 0, 0}

    如果你打印这个,它不会显示任何内容,因为字符串在第一个位置以空结尾(我猜这是你所说的错误......)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      • 2012-04-29
      • 1970-01-01
      • 2019-11-21
      • 2014-10-06
      • 1970-01-01
      相关资源
      最近更新 更多