【问题标题】:How to get the string size in bytes?如何以字节为单位获取字符串大小?
【发布时间】:2013-02-06 16:13:02
【问题描述】:

顾名思义,我的问题是如何获取C 中字符串的大小。如果我在没有malloc 的函数中声明它(字符串),那么使用sizeof 是否很好?或者,如果我已将其声明为指针?如果我用malloc 初始化它会怎样?我想要一个详尽的答复。

【问题讨论】:

  • 从您的问题中不清楚您是想知道“字符串”的大小还是保存“字符串”的字符数组/内存块的大小。
  • @alk 已编辑。希望更清楚。谢谢。

标签: c sizeof arrays


【解决方案1】:

您可以使用strlen。大小由终止的空字符决定,因此传递的字符串应该是有效的。

如果你想获取包含你的字符串的内存缓冲区的大小,并且你有指向它的指针:

  • 如果是动态数组(用malloc创建),是无法获取的 它的大小,因为编译器不知道指针指向什么。 (check this)
  • 如果是静态数组,可以使用sizeof获取其大小。

如果您对动态数组和静态数组的区别感到困惑,请查看this

【讨论】:

  • 实际大小为strlen()+1(1为终止符)
  • @0x69 字符串的大小通常定义为不包括空终止符。
  • @modifiablelvalue 这意味着 - 不可能直接从动态数组中获取大小。当然你可以存储大小,但这不是重点。
  • @artaxerxe: C 定义 char 是 1 个字节,但它没有定义一个字节是 8 位。因此,虽然char 确实就 C 而言始终是一个字节,但它不一定是一个八位字节,并且 C 标准之外的大部分世界都认为“字节”意味着“八位字节”。 char 大于 8 位的 C 实现是少数,但包括很多 DSP。由于各种原因,许多“可移植”代码无论如何都不会在 DSP 上运行,因此由您决定是否要假设一个字节是 8 位。 CHAR_BIT 的值可以肯定地告诉你。
  • @Dukeling Hm... 然后将带有memcpystrlen() 字节复制到其他(非空)缓冲区并打印。您将看到的将是您的新字符串 + 垃圾。这是我的论点,以字节为单位的字符串大小是strlen()+1。 (但是字符串 lengthstrlen())。
【解决方案2】:

使用strlen 获取以空字符结尾的字符串的长度。

sizeof 返回 数组 的长度而不是字符串。如果它是一个指针 (char *s),而不是一个数组 (char s[]),它将不起作用,因为它将返回指针的大小(在 32 位系统上通常为 4 个字节)。我相信数组将作为指针传递或返回,因此您将无法使用sizeof 检查数组的大小。

所以,只有当字符串跨越整个数组时(例如char s[] = "stuff"),才会将sizeof 用于静态定义数组返回你想要的(并且更快,因为它不需要循环查找空终止符)(如果最后一个字符是空终止符,则需要减去 1)。如果它不跨越整个数组,它就不会返回你想要的。

所有这些的替代方法实际上是存储字符串的大小。

【讨论】:

  • 请注意,sizeof 实际上并没有给出字符串的长度。对于字符串文字,sizeof 包括空终止符。对于char 的数组,sizeof 为您提供数组中的元素数量(这是一个比数组内容的字符串长度大的不可预测的数量)
  • 指出strlensizeof 返回两个根本不同的东西可能是有意义的。
  • 指针的大小在 32 位系统上总是 4 个字节。考虑 CHAR_BIT 是否为 32 位。除此之外,请考虑 16 位操作系统和编译器是否存在于该 32 位系统上。 CHAR_BIT 在 16 位操作系统和硬件上可能仍然是 32 位。指针的大小由编译器决定,而不是操作系统或硬件。如果编译器选择使用与操作系统或硬件相同的大小,那么这是编译器的选择。此外,不同的指针可能有不同的大小。
  • @modifiablelvalue 将“总是”更改为“通常”。
【解决方案3】:

虽然sizeof 适用于这种特定类型的字符串:

char str[] = "content";
int charcount = sizeof str - 1; // -1 to exclude terminating '\0'

如果str 是指针(sizeof 返回指针的大小,通常为 4 或 8)或指定长度的数组(sizeof 将返回与指定长度匹配的字节数,对于 char 类型是一样)。

只需使用strlen()

【讨论】:

  • 在你的例子中,因为 str 是一个类型名称,不应该用括号括起来吗?
  • @ramrunner str 是变量名。它是一个数组,所以sizeof str 将返回整个数组的大小(以字节为单位)。当数组像上面那样声明时,数组大小正好是字符串文字的大小,包括终止'\0'。而且sizeof 的优先级高于-,所以sizeof str 不需要任何括号,尽管我承认在这里为了清楚起见添加它们并不是一件坏事。
【解决方案4】:

如果您使用sizeof(),那么char *strchar str[] 将返回不同的答案。 char str[] 将返回字符串的长度(包括字符串终止符),而char *str 将返回指针的大小(因编译器而异)。

【讨论】:

    【解决方案5】:

    我喜欢用:

    (strlen(string) + 1 ) * sizeof(char)
    

    这将为您提供以字节为单位的缓冲区大小。您可以将其与 snprintf() 一起使用可能会有所帮助:

    const char* message = "%s, World!";
    char* string = (char*)malloc((strlen(message)+1))*sizeof(char));
    snprintf(string, (strlen(message)+1))*sizeof(char), message, "Hello");
    

    干杯!功能:size_t strlen (const char *s)

    【讨论】:

    • (1) strlen() 总是以字节为单位返回长度,将其乘以 1 不会增加任何内容; (2) 缓冲区的大小和它所包含的字符串的长度可能没有关系; (3) 您是否尝试过编译任何代码?
    • (1) 没有乘以一 (2) 我为指针分配字节,所以我使用字符串长度 * sizeof a char (inbytes) (3) 我一直使用它.
    • 如果你想建立一个代表,你需要通过提供好的答案来做到这一点。最新的编辑至少删除了以前的错误,但现在它甚至不是答案,而是评论。所有其他答案都引用strlen() 并给出一些有意义的解释,这不是一个值得投票的答案。
    • 如果你留下一个体面的答案,我会很高兴地删除反对票。如果你留下一个好的答案,我会很乐意投票。您的原始代码无法在任何 C 编译器上编译,无论是嵌入式还是其他。
    • 它不包含原始答案中的违规代码,因此与重点无关。 1/2 始终为零。别再用这种废话浪费我的时间了。
    猜你喜欢
    • 2011-09-08
    • 2013-04-26
    • 2012-02-01
    • 2011-06-17
    • 2013-02-01
    • 1970-01-01
    • 2016-01-25
    • 2011-03-22
    • 2016-04-08
    相关资源
    最近更新 更多