【问题标题】:What is the cause of this unexpected additional character in C?C 中这个意外的附加字符的原因是什么?
【发布时间】:2021-08-30 14:59:27
【问题描述】:

当我运行以下代码时:

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

int main() {
    static char foo[32];
    memset(foo, '0', sizeof(foo));
    printf("%s %d\n", foo, sizeof(foo));

    return 0;
}

我收到以下输出:

00000000000000000000000000000000☺ 32

字符串长度是 33,而它的大小是 32 字节,所以索引 32 处的“笑脸”字符似乎来自一些未分配的内存。我对这里发生的事情感到困惑,而且我似乎无法很好地用搜索查询来找到我正在寻找的东西。非常感谢任何建议。

【问题讨论】:

  • 问:所以索引 32 处的“笑脸”字符似乎来自一些未分配的内存。是的。您已将 32 个字符数组的所有 32 个字符初始化为 ASCII 数字“0”……但您忘记了终止字符串! C 字符串的最后一个字符必须是二进制“0”。结果是undefined behavior
  • 感谢您的帮助!
  • "字符串长度为 33" --> foo 不是 字符串,因为它缺少 null 字符 i>.

标签: c string memory


【解决方案1】:
printf() 中的

%s 需要一个指向 strings 的指针,这意味着 C 中的“一系列字符以空字符结尾”。

缓冲区foo 中的所有字节都由'0' 填充,因此缓冲区中没有终止空字符,printf() 将超出范围以找到终止空字符。

当您想要打印不是字符串的字符序列(不以空字符结尾的字符)时,您应该指定要打印的长度。

还要注意sizeof 返回size_t%d 格式说明符和要指定的长度(如果它作为参数给出)。传递具有错误类型的数据会调用未定义的行为。打印size_t 的正确格式说明符是%zu。 (注意size_t 是无符号的)。

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

int main() {
    static char foo[32];
    memset(foo, '0', sizeof(foo));
    printf("%.*s %zu\n", (int)sizeof(foo), foo, sizeof(foo));

    return 0;
}

【讨论】:

  • 感谢您的回答!我怀疑它与字符串中的终止字符有关,但我无法确定它。顺便说一句,为什么这个答案被否决了?
  • @SeanXie NMDV,但我怀疑用"%.*s" 打印一个字符数组对某些人来说是不寻常的。这是具有 32 个'0' 的 32 字节数组的正确解决方案。替代方法包括将foo[33]; 设为字符串 并使用"%s"
猜你喜欢
  • 2010-11-21
  • 2012-03-26
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-22
  • 1970-01-01
相关资源
最近更新 更多