scanf实现中的错误或标准中的示例中的错误? [英] Error in scanf implementation or error in example in standard?

查看:60
本文介绍了scanf实现中的错误或标准中的示例中的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下示例3在1999 C标准中给出了函数

fscanf:


示例3从stdin重复接受数量,单位

度量和项目名称:


#include< stdio.h>

/ * ... * /

int count;浮动定量; char单位[21],item [21];

do {

count = fscanf(stdin,%f%20s of%20s"& quant,单位,项目);

fscanf(stdin,"%* [^ \ n]");

} while(!feof(stdin)&& ;!ferror(stdin));


如果stdin流包含以下行:


2夸脱油

-12.8degrees Celsius

好​​运很多

10.0LBS

污垢

100ergs of energy


以上示例的执行将类似于以下

分配:


quant = 2; strcpy(单位,夸脱); strcpy(item,oil);

count = 3;

quant = -12.8; strcpy(单位,度);

count = 2; //C无法匹配o

count = 0; //l无法匹配%f

quant = 10.0; strcpy(单位,LBS); strcpy(item," dirt");

count = 3;

count = 0; //100e无法匹配%f

count = EOF;



我已经测试了几个实现,但没有一个获得最后一个案例

正确。在任何情况下,fscanf都不会返回0表示无法匹配

100ergs of energy使用%f。


实际行为会有所不同。有些会匹配''100'',让'e''未读:


quant = 100; strcpy(单位,ergs); strcpy(item,energy);

count = 3;


而其他人将匹配''100e'',留下''r' '未读:


quant = 100; strcpy(units," rgs"); strcpy(item,energy);

count = 3;


但是我还没有遇到一个实现该实例的实现标准中指定的
。这是实施中的失败还是标准本身的




-

Simon。

解决方案

Simon Biber写道:


以下示例3在1999 C标准中给出了函数

fscanf:


示例3从stdin中重复接受一个数量,一个单位为

的度量,以及项目名称:


#include< stdio.h>

/ * ... * /

int count;浮动定量; char单位[21],item [21];

do {

count = fscanf(stdin,%f%20s of%20s"& quant,单位,项目);

fscanf(stdin,"%* [^ \ n]");

} while(!feof(stdin)&& ;!ferror(stdin));


如果stdin流包含以下行:


2夸脱油

-12.8degrees Celsius

好​​运很多

10.0LBS

污垢

100ergs of energy


以上示例的执行将类似于以下

分配:


quant = 2; strcpy(单位,夸脱); strcpy(item,oil);

count = 3;

quant = -12.8; strcpy(单位,度);

count = 2; //C无法匹配o

count = 0; //l无法匹配%f

quant = 10.0; strcpy(单位,LBS); strcpy(item," dirt");

count = 3;

count = 0; //100e无法匹配%f

count = EOF;



我测试了几个实现,但没有一个获得最后一个案例

正确。在任何情况下,fscanf都不会返回0表示无法匹配

100ergs of energy使用%f。


实际行为会有所不同。有些会匹配''100'',让'e''未读:


quant = 100; strcpy(单位,ergs); strcpy(item,energy);

count = 3;


而其他人将匹配''100e'',留下''r' '未读:


quant = 100; strcpy(units," rgs"); strcpy(item,energy);

count = 3;


但是我还没有遇到一个实现该实例的实现标准中指定的
。这是实施中的失败还是标准本身的




n1124中的脚注245指出:

" fscanf将最多一个输入字符推回到输入流中。

因此,某些strtod,strtol等可接受的序列,

对于fscanf是不可接受的。


这是在响应中添加的缺陷报告#22:
http://www.open-std.org/jtc1/sc22/wg...cs/dr_022.html


如果是100ergs, fscanf读到r之后才意识到

e不是数字的一部分,但在那一点上,鉴于一个

字符回击限制,它不能再推回r和

e所以它必须返回失败,因为100e不是有效数字。

许多实现允许多个字符后推并在fscanf函数中获取这个事实的优势,因此行为你

见过。从技术上讲,这样的实现违反了

标准,但许多实现者的情绪是,

要求是不合理的,他们只是生活在不合规之中。


Robert Gamble


Robert Gamble说:


< snip>


许多实现允许多个字符回送并在fscanf函数中利用这个事实的优势,因此你的行为

见过。技术上这样的实现违反了

标准



为什么?


- < br $>
Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:rjh在上述域名中, - www。


" Robert Gamble" < rg ******* @ gmail.comwrote:


Simon Biber写道:


我已经测试了几个实现,但没有一个获得最后一个案例

吧。在任何情况下,fscanf都不会返回0表示无法匹配

100ergs of energy使用%f。


实际行为会有所不同。有些会匹配''100'',让'e''未读:


quant = 100; strcpy(单位,ergs); strcpy(item,energy);

count = 3;


而其他人将匹配''100e'',留下''r' '未读:


quant = 100; strcpy(units," rgs"); strcpy(item,energy);

count = 3;


但是我还没有遇到一个实现该实例的实现标准中指定的
。这是实施中的失败还是标准本身的




n1124中的脚注245指出:

" fscanf将最多一个输入字符推回到输入流中。

因此,stsod,strtol等可接受的某些序列,对于fscanf来说是不可接受的。



是的,但是footneet不是规范性的。严格来说,标准的两个部分之间存在

冲突;脚注清楚说明

在这种情况下,意图是关于单个字符的部分

输入流的推回缓冲区会覆盖关于解析的部分

数字,但如果在下一个TC的

_normative_文本中明确表示会更好。


Richard


The following Example 3 is given in the 1999 C standard for the function
fscanf:

EXAMPLE 3 To accept repeatedly from stdin a quantity, a unit of
measure, and an item name:

#include <stdio.h>
/* ... */
int count; float quant; char units[21], item[21];
do {
count = fscanf(stdin, "%f%20s of %20s", &quant, units, item);
fscanf(stdin,"%*[^\n]");
} while (!feof(stdin) && !ferror(stdin));

If the stdin stream contains the following lines:

2 quarts of oil
-12.8degrees Celsius
lots of luck
10.0LBS of
dirt
100ergs of energy

the execution of the above example will be analogous to the following
assignments:

quant = 2; strcpy(units, "quarts"); strcpy(item, "oil");
count = 3;
quant = -12.8; strcpy(units, "degrees");
count = 2; // "C" fails to match "o"
count = 0; // "l" fails to match "%f"
quant = 10.0; strcpy(units, "LBS"); strcpy(item, "dirt");
count = 3;
count = 0; // "100e" fails to match "%f"
count = EOF;

I have tested several implementations and none of them get the last case
right. In no case does fscanf return 0 indicating failure to match
"100ergs of energy" with "%f".

The actual behaviour varies. Some will match ''100'', leaving the ''e'' unread:

quant = 100; strcpy(units, "ergs"); strcpy(item, "energy");
count = 3;

While others will match ''100e'', leaving the ''r'' unread:

quant = 100; strcpy(units, "rgs"); strcpy(item, "energy");
count = 3;

But I am yet to come across an implementation that does what the example
in the Standard specifies. Is this a failure in the implementations or
in the Standard itself?

--
Simon.

解决方案

Simon Biber wrote:

The following Example 3 is given in the 1999 C standard for the function
fscanf:

EXAMPLE 3 To accept repeatedly from stdin a quantity, a unit of
measure, and an item name:

#include <stdio.h>
/* ... */
int count; float quant; char units[21], item[21];
do {
count = fscanf(stdin, "%f%20s of %20s", &quant, units, item);
fscanf(stdin,"%*[^\n]");
} while (!feof(stdin) && !ferror(stdin));

If the stdin stream contains the following lines:

2 quarts of oil
-12.8degrees Celsius
lots of luck
10.0LBS of
dirt
100ergs of energy

the execution of the above example will be analogous to the following
assignments:

quant = 2; strcpy(units, "quarts"); strcpy(item, "oil");
count = 3;
quant = -12.8; strcpy(units, "degrees");
count = 2; // "C" fails to match "o"
count = 0; // "l" fails to match "%f"
quant = 10.0; strcpy(units, "LBS"); strcpy(item, "dirt");
count = 3;
count = 0; // "100e" fails to match "%f"
count = EOF;


I have tested several implementations and none of them get the last case
right. In no case does fscanf return 0 indicating failure to match
"100ergs of energy" with "%f".

The actual behaviour varies. Some will match ''100'', leaving the ''e'' unread:

quant = 100; strcpy(units, "ergs"); strcpy(item, "energy");
count = 3;

While others will match ''100e'', leaving the ''r'' unread:

quant = 100; strcpy(units, "rgs"); strcpy(item, "energy");
count = 3;

But I am yet to come across an implementation that does what the example
in the Standard specifies. Is this a failure in the implementations or
in the Standard itself?

Footnote 245 in n1124 states:
"fscanf pushes back at most one input character onto the input stream.
Therefore, some sequences that are acceptable to strtod, strtol, etc.,
are unacceptable to fscanf."

This was added in response to Defect Report #22:
http://www.open-std.org/jtc1/sc22/wg...cs/dr_022.html.

In the case of 100ergs, fscanf reads up to the r before realizing that
the "e" is not part of the number but at that point, given the one
character pushback limit, it can no longer push back both the r and the
e so it has to return with a failure since 100e is not a valid number.
Many implementations allow more than one character pushback and take
advantage of this fact in the fscanf function, hence the behavior you
have seen. Technically such implementations are in violation of the
Standard but the sentiment among many implementors is that the
requirement is unjustified and they just live with non-conformance.

Robert Gamble


Robert Gamble said:

<snip>

Many implementations allow more than one character pushback and take
advantage of this fact in the fscanf function, hence the behavior you
have seen. Technically such implementations are in violation of the
Standard

Why?

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.


"Robert Gamble" <rg*******@gmail.comwrote:

Simon Biber wrote:

I have tested several implementations and none of them get the last case
right. In no case does fscanf return 0 indicating failure to match
"100ergs of energy" with "%f".

The actual behaviour varies. Some will match ''100'', leaving the ''e'' unread:

quant = 100; strcpy(units, "ergs"); strcpy(item, "energy");
count = 3;

While others will match ''100e'', leaving the ''r'' unread:

quant = 100; strcpy(units, "rgs"); strcpy(item, "energy");
count = 3;

But I am yet to come across an implementation that does what the example
in the Standard specifies. Is this a failure in the implementations or
in the Standard itself?


Footnote 245 in n1124 states:
"fscanf pushes back at most one input character onto the input stream.
Therefore, some sequences that are acceptable to strtod, strtol, etc.,
are unacceptable to fscanf."

True, but feetneet are not normative. Strictly speaking, there''s a
conflict between two parts of the Standard; the footnote makes it clear
that in this case, the intent was that the part about a single character
pushback buffer for input streams overrides the part about parsing
numbers, but it would be better if that were made explicit in the
_normative_ text in the next TC.

Richard


这篇关于scanf实现中的错误或标准中的示例中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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