【问题标题】:How to concatenate a unicode string literal with bytes?如何将 unicode 字符串文字与字节连接起来?
【发布时间】:2016-02-25 19:39:58
【问题描述】:

考虑到这个 USB 字符串描述符:

#define USB_PRODUCT_STRING_DESCRIPTOR_LENGTH (34U)
#define USB_DESCRIPTOR_TYPE_STRING (0x03U)

uint8_t UsbProductString[USB_PRODUCT_STRING_DESCRIPTOR_LENGTH] = {
    USB_PRODUCT_STRING_DESCRIPTOR_LENGTH,
    USB_DESCRIPTOR_TYPE_STRING,
    'C', 0x00U,
    'O', 0x00U,
    'M', 0x00U,
    'P', 0x00U,
    'O', 0x00U,
    'S', 0x00U,
    'I', 0x00U,
    'T', 0x00U,
    'E', 0x00U,
    ' ', 0x00U,
    'D', 0x00U,
    'E', 0x00U,
    'V', 0x00U,
    'I', 0x00U,
    'C', 0x00U,
    'E', 0x00U,
};

有什么方法可以以更容易阅读的方式来表示它吗?可能使用u"" 字符串语法?

【问题讨论】:

  • 发布USB_DESCRIPTOR_TYPE_STRING 定义。
  • 这些是宽字符 (wchar_t)、某种 Unicode 编码,还是只是带有交错零的 ASCII?
  • @e0k 因为 wchar_t 可能不是 2 uint8_t 它看起来不像宽字符。也许是 UTF16-LE? László Monda - 请提供更多细节。
  • @chux 刚刚发布了USB_DESCRIPTOR_TYPE_STRING 定义。
  • @e0k 看起来 USB 使用 UTF-16LE。

标签: c string unicode byte concatenation


【解决方案1】:

如何将 unicode 字符串文字与字节连接起来?

我认为没有办法解决标题问题。

有什么方法可以以更容易阅读的方式来表示它吗?可能使用 u"" 字符串语法?

没有简单的方法来清楚地处理连接 3 个字段。

回想一下u"some text"char16_t 一起使用,可能/可能不代表UTF-16 编码。

也许简单地使用 3 字段类型?

#include <stddef.h>
#include <uchar.h>
#include <stdio.h>

//#define USB_PRODUCT_STRING_DESCRIPTOR_LENGTH (34U)
#define USB_DESCRIPTOR_TYPE_STRING 1
#define UPS_SIZE(S) (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(S) - 2 /*null character*/)

typedef struct {
  uint8_t length;
  uint8_t descriptor_type;
  char16_t descriptor[127];  // 127 Maximum length
} USBProductString_T;

int main(void) {
  #if __STDC_UTF_16__ == 1
    puts("values of type char16_t are UTF-16 encoded.");
  #else
    puts("values of type char16_t are not known to be UTF-16 encoded.");
    return 0;
  #endif


  #define COMPOSITE_DEVICE u"COMPOSITE DEVICE"
  USBProductString_T UsbProductString = 
    { UPS_SIZE(COMPOSITE_DEVICE), USB_DESCRIPTOR_TYPE_STRING, COMPOSITE_DEVICE };


  printf("%u %u %zu\n", 1U*UsbProductString.length, 1U*UsbProductString.descriptor_type, 
      sizeof UsbProductString);
  return 0;
}

输出

values of type char16_t are UTF-16 encoded.
34 1 256

进一步解决 OP 附加限制 - 空格:

将常量与活动类型分离。使用char16_t[] 形成UsbProductString,然后做一个特殊的初始化/复制/比较/创建函数来使用它。各种方法取决于未说明的设计约束。

static char16_t UsbProductString[] = u"COMPOSITE DEVICE";

void FormString(uint8_t buf[], const char16_t *s) {
  unsigned bi = 0,si = 0;
  buf[++bi] = USB_DESCRIPTOR_TYPE_STRING
  while (s[si]) {
    buf[++bi] = s[si] % 256;
    buf[++bi] = s[si] / 256;
    si++;
  }
  buf[0] == ++bi;
}

uint8_t buf[sizeof UsbProductString - 2  + 2];  // string has an unneeded null character
FormString(buf, UsbProductString);
Send(buf);

您的帖子需要一个具有 1) 灵活数组成员和 2) 用 initialized 值声明它的结构。据我了解C,这是不可能的。将 UsbProductString[] 视为一个数组并尝试将第一个字段插入字符串的一部分是正确的,但这会牺牲可读性 - 尝试创建“UTF-16”uint8_t 数据。

【讨论】:

  • 这看起来很紧,谢谢!我唯一的抱怨是 descriptor 字段总是占用 254 个字节。这对微控制器来说是相当浪费的。有什么办法可以解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 2023-01-24
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
相关资源
最近更新 更多