【问题标题】:multiple null terminated strings in single buffer in CC中单个缓冲区中的多个空终止字符串
【发布时间】:2017-11-28 18:09:59
【问题描述】:

需要制作具有以下格式的字符串并将其放入单个缓冲区[1000]。请注意,\x00 是空终止符。

@/foo\x00ACTION=add\x00SUBSYSTEM=block\x00DEVPATH=/devices/platform/goldfish_mmc.0\x00MAJOR=command\x00MINOR=1\x00DEVTYPE=harder\x00PARTN=1

所以本质上我需要将以下以 null 结尾的字符串打包到一个缓冲区中

@/foo  
ACTION=add  
SUBSYSTEM=block  
DEVPATH=/devices/platform/goldfish_mmc.0  
MAJOR=command  
MINOR=1  
DEVTYPE=harder  
PARTN=1  

我该怎么做?

【问题讨论】:

  • char buffer[1000] = "@/foo\000ACTION=add\000SUBSYSTEM=block\000 ...等页
  • "foo\x00ACTION" 不起作用,因为 \x00AC 在这里被视为单个字符(A 和 C 也是十六进制数字),如果这让您感到困惑。
  • 您可以使用\0 而不是\x00,这将避免\x00AC 被视为宽字符的问题,事实上\0 是指定的首选C 方式NUL
  • 你是如何得到这个 list 字符串的?问的原因是,根据他们来自哪里,可能有更快的方法来做到这一点
  • @AhmedMasud 我更喜欢\000,因为当你有两个字符串“abc”“123”时,"abc\0123" 不是预期的

标签: c string buffer packing


【解决方案1】:

您需要一次复制每个字符串,跟踪上一次复制停止的位置并在下一次复制之后开始。

char *p = buffer;
strcpy(p, "@/foo");
p += strlen(p) + 1;
strcpy(p, "ACTION=add");
p += strlen(p) + 1;
...

【讨论】:

    【解决方案2】:

    您可以使用%c 来打印带有sprintf 的数字零,如下所示:

    char *a[] = {"quick", "brown", "fox", "jumps"};
    int n = 0;
    char buf[100];
    for (int i = 0 ; i != 4 ; i++) {
        n += sprintf(buf+n, "%s%c", a[i], 0);
    }
    

    Demo

    【讨论】:

    • 或者,更简单一点,n += sprintf(buf+n, "%s%c", a[i], 0);
    • @Ctx 你说得对,谢谢!我不确定printf 的返回值是否包含尾随零而不将其解释为空终止符。
    【解决方案3】:

    您可以使用包含显式嵌入 NUL 字符的字符串来初始化缓冲区:

    char buffer[1000] =
      "@/foo\0"
      "ACTION=add\0"
      "SUBSYSTEM=block\0"  
      "DEVPATH=/devices/platform/goldfish_mmc.0\0"
      "MAJOR=command\0"
      "MINOR=1\0"
      "DEVTYPE=harder\0"  
      "PARTN=1";
    

    或者您可以使用memcpy 显式复制它:

    char str[] =
      "@/foo\0"
      "ACTION=add\0"
      "SUBSYSTEM=block\0"  
      "DEVPATH=/devices/platform/goldfish_mmc.0\0"
      "MAJOR=command\0"
      "MINOR=1\0"
      "DEVTYPE=harder\0"  
      "PARTN=1";
    char buffer[1000];
    
    memcpy(buffer, str, sizeof(str));
    

    这里,编译器会连接相邻的字符串常量,但只有最后一个字符串会得到一个隐式 NUL;所有其他人都有一个明确的 NUL。

    此外,将"\01" 之类的字符串(在这种情况下实际上并未出现)分解为"\0" "1" 可防止编译器将"\01" 视为单个字符串{ 0x01, 0x00 }(带有隐式尾随NUL ),而是将 is 视为预期的两个字符串 { 0x00, 0x31, 0x00 }(也带有隐式尾随 NUL)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-27
      • 2012-01-02
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 2021-03-28
      相关资源
      最近更新 更多