【问题标题】:C print whole string variable (ignore \0 termination)C 打印整个字符串变量(忽略 \0 终止)
【发布时间】:2014-03-08 17:38:20
【问题描述】:

一个例子说一千多个单词:

unsigned char *hello = (unsigned char*)malloc(STR_LEN * sizeof(unsigned char));
const char *str= "haha";
memcpy(hello, str, strlen(str) + 1);

如何打印整个hello-variable 的内容(printf("%s",..) 只会尊重\0-终止之前的部分,而不是所有STR_LEN 字符)。

【问题讨论】:

  • 这样做是未定义的行为,因为内存没有初始化。
  • 我知道...在正常情况下,这没有任何意义。但是我要比较一些ASM操作,想比较\0后面的位。
  • 知不知道,它仍然是UB。
  • @WhozCraig - 我猜调试器一定会左右崩溃,不是吗?事实上,UB 是一个理论概念,在实际系统中,结果受到合理限制。
  • 这里更有趣的问题可能是,如果想要比较“后面的位”,那么人们可能不想将字节打印为 ASCII 字符,而是打印出它们的某些值方便的形式,例如十六进制。

标签: c variables printf null-terminated


【解决方案1】:

可以使用fwrite写入无格式数据:

char buf[4] = { 1, 2 };

fwrite(buf, 1, 4, stdout);   // writes the bytes 1, 2, 0, 0

您可以使用fwrite(hello, 1, STR_LEN, stdout),但请注意,您不能读取未初始化的数据(因此您应该改用calloc 或以其他方式初始化数据)。

【讨论】:

  • +1 作为未初始化的数据评估警察。 (有人必须这样做)。
  • 实际系统上可能遇到的真正问题不是读取未初始化的数据,而是未过滤 到终端。
  • @ChrisStratton: | hexdump -C :-)
【解决方案2】:

您必须编写自己的 for 循环,从 hello 到 hello+STR_LEN,并一次打印一个字符。

for (unsigned char *c = hello, e = hello +STR_LEN; c < e; ++c) {
    printf("%c", *c);
}

【讨论】:

  • 不,你不会,正如其他人所指出的那样。但是,如果目标实际上是查看原始数据本身,其中字符表示不是很有用,那么像这样带有格式字符串(如%02x )的东西可能是生成信息丰富的小十六进制转储的良好开端
【解决方案3】:
int i;
for(i = 0; i < STR_LEN; i++) {
    putchar(hello[i]);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多