是与fgets()返回NULL用短bufffer兼容? [英] Is fgets() returning NULL with a short bufffer compliant?

查看:278
本文介绍了是与fgets()返回NULL用短bufffer兼容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在单元测试包含与fgets()函数,碰到了意想不到的结果时的缓冲区大小 N'LT; 2 。显然,这样的缓冲区大小是愚蠢的,但测试正在探索其他的情况。结果
简体code:

In unit testing a function containing fgets(), came across an unexpected result when the buffer size n < 2. Obviously such a buffer size is foolish, but the test is exploring corner cases.
Simplified code:

#include <error.h>
#include <stdio.h>

void test_fgets(char * restrict s, int n) {
  FILE *stream = stdin;
  s[0] = 42;
  printf("< s:%p n:%d stream:%p\n", s, n, stream);
  char *retval = fgets(s, n, stream);
  printf("> errno:%d feof:%d ferror:%d retval:%p s[0]:%d\n\n",
    errno, feof(stream), ferror(stream), retval, s[0]);
}

int main(void) {
  char s[100];
  test_fgets(s, sizeof s);  // Entered "123\n" and works as expected
  test_fgets(s, 1);         // fgets() --> NULL, feof() --> 0, ferror() --> 0
  test_fgets(s, 0);         // Same as above
  return 0;
}

令人惊讶的是,与fgets()收益 NULL 没有的feof()也不 FERROR() 1 。结果
的C规格,下面,似乎在这难得一遇沉默。

What is surprising is that fgets() returns NULL and neither feof() nor ferror() are 1.
The C spec, below, seems silent on this rare case.

问题:

时返回 NULL 没有设定的feof()也不 FERROR()合规行为?结果
可能不同的结果是合规行为?结果
是否有所作为,如果 N 为1或小于1?

Is returning NULL without setting feof() nor ferror() compliant behavior?
Could a different result be compliant behavior?
Does it make a difference if n is 1 or less than 1?

平台:gcc版本4.5.3目标:为i686-PC-cygwin的

Platform: gcc version 4.5.3 Target: i686-pc-cygwin

参考C11§7.21.7.2在与fgets 函数读取比的 N ...在与fgets 函数返回的取值如果成功的。如果遇到文件结束-的的任何字符已经被读入数组,数组的内容保持不变,空返回指针。如果操作过程中发生读取错误,数组的内容不确定,并返回一个空指针。

Ref C11 §7.21.7.2 "The fgets function reads at most one less than the number of characters specified by n ... The fgets function returns s if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned.

相关贴子搜索
<一href=\"http://stackoverflow.com/questions/21724004/minishell-in-c-how-to-use-feof-and-ferror-for-fgets\">minishell在C.如何使用的feof和ferror用于与fgets 结果
<一href=\"http://stackoverflow.com/questions/12716276/trouble-creating-a-shell-in-c-seg-fault-and-ferror\">Trouble创造C(赛格故障和ferror)外壳结果
<一href=\"http://stackoverflow.com/questions/9059486/fputs-fgets-ferror-questions-and-c-equivalents\">fputs(),与fgets(),ferror()函数的问题和C ++等效结果
与fgets的返回值()

Related postings
minishell in C. How to use feof and ferror for fgets
Trouble creating a shell in C (Seg-Fault and ferror)
fputs(), fgets(), ferror() questions and C++ equivalents
Return value of fgets()

上解答评论

@Shafik Yaghmour以及presented的整体问题:因为C规格并没有提到它的时候不读的任何的数据也不会写的任何的数据做什么到取值时( N'LT = 0 ),它是未定义的行为。因此,任何合理的反应应该是可以接受的,如符 NULL ,设置任何标志,独自离开缓冲。

@Shafik Yaghmour well presented the overall issue: since the C spec does not mention what to do when it does not read any data nor write any data to s when (n <= 0), it is Undefined Behavior. So any reasonable response should be acceptable such as return NULL, set no flags, leave buffer alone.

至于何时ñ== 1 ,@Oliver马修斯答案,@马特麦克纳布表示注释一个C规格的缺乏明确的考虑<$ C的缓冲区应该发生什么$ C>ñ== 1 。的C规格的看起来的青睐的ñ== 1 应该返回与缓冲区指针S [0] =缓冲区='\\ 0',但不够明确的。

As to what should happen when n==1, @Oliver Matthews answer and @Matt McNabb comment indicate a C spec's lack of clarity considering a buffer of n == 1. The C spec seems to favor a buffer of n == 1 should return the buffer pointer with s[0] == '\0', but is not explicit enough.

推荐答案

该行为是在的glibc ,更新版本的发布不同的 n ==可1 ,它返回取值表示成功,这不是 7.19.7.2 的与fgets函数的段落的 2 的它说(的这是两个C99和C11一样,重点煤矿的):

The behavior is different in newer releases of glibc, for n == 1, it returns s which indicates success, this is not an unreasonable reading of 7.19.7.2 The fgets function paragraph 2 which says (it is the same in both C99 and C11, emphasis mine):

字符*与fgets(字符*限制S, INTñ,FILE *流限制);

char *fgets(char * restrict s, int n, FILE * restrict stream);

在与fgets函数的读取小于n指定的字符数少至多一个
  从流指向的流进所述阵列由s指向。无需额外的
  字符换行字符(保持不变)后,读或尾文件之后。 一个空字符后,立即最后一个字符读入数组写的。

The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.

不是非常有用的,但并不违反任何表示,在标准,将在最 0 字符阅读和空终止。这样的成绩,你看到的样子被固定在后来的的glibc 的版本中的错误。文件所涵盖的段落也清楚不是目的,也不是读取错误的 3 的:

not terribly useful but does not violate anything said in the standard, it will read at most 0 characters and null-terminate. So the results you are seeing looks like a bug that was fixed in later releases of glibc. It also clear not an end of file nor a read error as covered in paragraph 3:

[...]如果-的文件到底是遇到并没有字符被读入数组,数组的内容保持不变,返回一个空指针。如果操作过程中发生读取错误,数组的内容不确定,并返回一个空指针。

[...]If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned.

至于最后一种情况,其中ñ== 0 这看起来简直是不确定的行为的草案C99标准节 4。一致性的段落的 2 的说(的重点煤矿的):

As far as the final case where n == 0 this looks like it is simply undefined behavior the draft C99 standard section 4. Conformance paragraph 2 says (emphasis mine):

如果出现一个约束之外的''应当''或''不得''要求侵犯,行为是不确定的。 未定义行为另有说明本标准由词''不确定的行为''或通过行为的任何明确定义的疏漏。有这三个重点之间无明显差异;他们都形容''是不确定的行为'。

If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.

的措辞是C11相同。这是不可能读最多-1字符,这既不是文件的目的,也不读取错误。所以我们在这种情况下的行为没有明确的定义。看起来像一个缺陷,但我无法找到这个覆盖任何缺陷报告。

the wording is the same in C11. It is impossible to read at most -1 characters and it is neither an end of file nor a read error. So we have no explicit definition of the behavior in this case. Looks like a defect but I can not find any defect reports that cover this.

这篇关于是与fgets()返回NULL用短bufffer兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆