【发布时间】:2020-11-23 12:52:16
【问题描述】:
tl;dr
如果下一个换行符是stdin 中的nth 字符,是否违反约束?
实施gets_s(),我想知道我认为标准措辞中的矛盾之处。
标准的定义(附件 K)如下(强调我的):
char *gets_s(char *s, rsize_t n);运行时约束
[...] 换行符、文件结尾或读取错误应在读取中发生 n-1 个字符来自
stdin。
[...]
gets_s函数读取的字符数最多比n指定的字符数少一个 从stdin指向的流,进入s指向的数组。无需额外 在换行符(被丢弃)或文件结尾之后读取字符。 丢弃的换行符不计入读取的字符数。
让我们假设换行符作为输入的nth 字符出现。最明显的例子是n == 1,stdin 流中的下一个字符是换行符。
我应该...
-
...认为这是违反约束(
n - 1 == 0中没有换行符从stdin读取的字符)?这意味着调用约束违规处理程序,并返回NULL。 -
...读取换行符,丢弃它(不计入读取的字符数),然后返回
s?
任何一种情况都会看到s[0] = '\0',并且(包括在内)从stdin 读取/丢弃的换行符。
【问题讨论】:
-
@AdrianMole:由于标准的其余部分处理透明缓冲的问题,并且流的缓冲可能是
_IOFBF以及_IOLBF或_IONBF,我看不出有理由假设这个函数的定义突然玩起了“读取”和“处理”的游戏。 -
@AdrianMole:嗯,我的第一个引用块的第一句话与我的第二个引用块的最后一句话相矛盾。 这是手头的问题。 除非您觉得我的问题有什么不清楚的地方,否则请随意尝试实际的答案...(无意冒犯,我只是觉得您的印象是在此处的评论中暗示答案。)
-
@AdrianMole 但是
new-line character does not count towards number of characters read.当gets_s在abc之后读取<newline>时,读取的字符数保持在3,因为换行符不计算在内。这正是问题所在。因为对于char b[4]; gets(b)提供abc\n作为输入很好。 -
标准引用的第一部分指出前 n-1 (!!) 个字符中没有换行符是违反约束(调用失败)。这就是矛盾。我完全同意您的 interpretation 是有道理的(n 是缓冲区大小,因此会有 n-1 个字符的空间加上一个零终止符)。所以我们在标准的措辞中有一个“错误”?这是一个答案,而不是试图澄清问题的评论。
-
变量
n是否在gets_s函数的范围内发生变化是一个不相关的实现细节。 我的 实现倒计时,因为除非必要,否则我不相信生成本地循环计数器,并且我不需要函数末尾的n的原始值(而不是s的原始值)。
标签: c language-lawyer