【问题标题】:C - strcpy() function restrictionsC - strcpy() 函数限制
【发布时间】:2020-06-22 17:12:42
【问题描述】:

我是 C 编程的新手,我很难理解它的某些方面,包括 strcpy() 函数。

我正在做一些测验,并通过了以下问题:

为保证以下strcpy(d,s)调用的正确性,必须始终满足以下哪个条件:

一个。 sizeof(d) >= strlen(s) + 1

b. sizeof(d) >= sizeof(s)

c。 sizeof(d) >= strlen(s)

d。 strlen(d) >= strlen(s)

e。 strlen(d) >= strlen(s) + 1

经过一番研究,我发现目标字符串的大小应该足够大,以存储复制的字符串。 Source here。这导致我选择 b 或 d。

但是正确答案是“a”,我不明白为什么,也找不到任何文档。有人可以更详细地解释strcpy()的限制是什么吗?

【问题讨论】:

  • ds 是如何声明的,它们都是静态数组还是指针? sizeof 不适用于静态和动态数组(例如 int a[20]int* a
  • @Chase,很遗憾我没有这些信息。这是问题中提供给我的所有信息。

标签: c


【解决方案1】:

这有点取决于变量是如何声明和/或定义的,但从答案是a这一事实来看,我很肯定这就是它们的声明和定义方式-

// Assume SIZE_0 and SIZE_1 are some integer values
char d[SIZE_0];
char s[SIZE_1];

// Assign a bunch of characters to `s` here and null terminate it
// Assume `s` now has `LEN` number of characters + 1 for the null terminator, for a total of `LEN + 1`
// Of course, `LEN + 1` is either less than, or equal to, `SIZE_1`

现在让我们快速清除这些值-

  • strlen(s) -> 返回LEN,因为它计算空终止符之前的字符数
  • sizeof(s) -> 返回SIZE_1
  • sizeof(d) -> 返回SIZE_0
  • strlen(d) -> 不像你想的那样工作,strlen 没有空终止符就不能工作,目前d 没有价值 - 所以没有长度,除非你设置,否则即使 0 也不会计算在内d[0]'\0' 你自己

因此,很明显,要使strcpy(d, s) 起作用,sizeof(d)(这是唯一有效的调用)必须大于或等于 LEN + 1(对于来自 s 的所有字符,LEN和 +1 用于空终止符)。

当然,s 上的strlen 将返回LEN,所以我们需要strlen(s) + 1

就是为什么你需要sizeof(d) 大于或等于strlen(s) + 1

我必须说,如果strlen 确实返回了字符串的容量(又名size),而不是当前长度,那么您的假设将起作用.

归根结底,请始终记住 容量 (size) 和 length 之间的区别,尤其是在 C 语言中。

【讨论】:

  • 所以我们假设在调用 strcpy(d,s) 时 d 没有赋值?为这些变量赋值时是否必须使用空终止符?意思是,如果 s 没有空终止符怎么办?
  • @ElenaM。是的!因为如果 d 分配了一个以空字符结尾的字符串,则选项 c 也是正确的,因为那时 strlen 是一个有效的调用。
  • 我还应该提一下,选项 B 也是正确的(分配与否),但这确实是在推动它,因为这不是 最小边界
  • 再次询问,因为您可能看不到我的编辑。为这些变量赋值时是否必须使用空终止符?意思是,如果 s 没有空终止符怎么办?
  • @ElenaM。 C 字符串应始终以空字符结尾,否则您将走向未定义的行为领域,strlen 之类的库函数不适用于非空字符结尾的字符串,请参阅here
【解决方案2】:

它正在复制带有空终止符的字符字节序列。例如字符串“ABC”表示为 65,66,67,0。

strlen 计算字符串的长度,不包括空终止符(例如,3 表示“ABC”)。 sizeof(对于数组)为您提供为数组预留的内存量。它包含的字符串可能更短。

char s[20] = "ABC";会给你一个长度为 3 的字符串,使用 4 个字节,包括终止符,在 20 个字节的保留内存空间中。

为了安全地从 s 复制到 d,您需要在 d 中有足够的空间来接收字符串及其终止符(没有终止符,您将没有有效的字符串)。因此 strlen(s)+1。

s 的大小无关紧要,因为不会复制所有保留空间。 strlen(d) 也无关紧要 - d 中的任何现有字符串都将被覆盖。

所以选项a是正确的。

【讨论】:

    【解决方案3】:

    C 中的所有字符串(strcpy 等函数使用的那种字符串)必须有一个 nul 终止符(一个零值 char 表示字符串的结束)。因此,要存储像"abc" 这样的字符串,您将需要任何char[] 数组具有至少四个 元素:一个用于每个字母加上一个用于nul-终止符。

    strlen() 函数返回给定字符串中的字符数不包括 nul-terminator;但是strcpy() 函数复制所有字符包括终止符,因此目标缓冲区必须至少是源的一个'chargreater than thestrlen`。

    另请注意,sizeof(d) 计算d 被声明为char数组 时起作用(例如char d[42]);如果将该数组传递给一个函数,它将“衰减”为一个指针,并且该函数不会(隐式)知道该数组的大小;请参阅此讨论:How to find the 'sizeof' (a pointer pointing to an array)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 2011-09-03
      • 2015-01-27
      • 2021-08-12
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多