scanf(“%d%d",& x,& x)是否定义正确? [英] Is scanf("%d%d", &x, &x) well defined?

查看:239
本文介绍了scanf(“%d%d",& x,& x)是否定义正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码定义是否正确?

Is the following code well defined?

#include <stdio.h>

int ScanFirstOrSecond(const char *s, int *dest) {
    return sscanf(s, "%d%d", dest, dest);
}

int main(void) {
    int x = 4;
    ScanFirstOrSecond("5", &x);
    printf("%d\n", x);  // prints 5

    // Here is the tricky bit
    ScanFirstOrSecond("6 7", &x);
    printf("%d\n", x);  // prints 7
    return 0;
}

换句话说,...参数是否暗含了restrict?

In other words, do the ... arguments have an implied restrict to them?

我找到的最适用的C规范是

The most applicable C spec I found is

fscanf函数依次执行格式的每个指令. ... C11dr§7.21.6.24

The fscanf function executes each directive of the format in turn. ... C11dr §7.21.6.2 4

推荐答案

简短的答案是:是的,它已定义:

scanf将尝试将stdin中的字节序列转换为以10为底的整数,并带有可选的初始空格和可选的符号.如果成功,该号码将存储在x中. scanf然后将再次执行这些步骤.返回值可以是EOF012,对于后一个2,最后转换的数字将存储在x中.

scanf will attempt to convert a sequence of bytes from stdin as an integer written in base 10 with optional initial spaces and an optional sign. If successful, the number will be stored into x. scanf will then perform these steps a second time. The return value can be EOF, 0, 1 or 2, and for the latter 2, the last number converted will have been stored into x.

长答案有些微妙:

似乎C标准确实指定了值以格式字符串的顺序存储.引用C11标准:

It seems the C Standard does specify that the values are stored in the order of the format string. Quoting the C11 Standard:

7.21.6.2 fscanf函数

...

4 fscanf函数依次执行格式的每个指令.当所有指令均已执行或指令失败(如下所述)时,该函数将返回.

4 The fscanf function executes each directive of the format in turn. When all directives have been executed, or if a directive fails (as detailed below), the function returns.

...

7作为转换规范的指令定义了一组匹配的输入序列,如下文针对每个说明符所述.转换规范在以下步骤中执行:

7 A directive that is a conversion specification defines a set of matching input sequences, as described below for each specifier. A conversion specification is executed in the following steps:

...

10除了在%指定符的情况下之外,将输入项(或者在%n指令的情况下,输入字符的数目)转换为适合于转换说明符的类型.如果输入项不是匹配序列,则指令的执行失败:此条件是匹配失败.除非*指示分配抑制,否则转换结果将放置在尚未接收转换结果的format参数后面的第一个参数指向的对象中.

10 Except in the case of a % specifier, the input item (or, in the case of a %n directive, the count of input characters) is converted to a type appropriate to the conversion specifier. If the input item is not a matching sequence, the execution of the directive fails: this condition is a matching failure. Unless assignment suppression was indicated by a *, the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result.

...

16如果在第一次转换(如果有)完成之前发生输入失败,则fscanf函数将返回宏EOF的值.否则,该函数将返回分配的输入项的数量,如果早期匹配失败,该数量将少于所提供的输入项的数量,甚至为零.

16 The fscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.

在本规范的其他地方,甚至都没有提到对输出对象的任何访问.

Nowhere else in this specification are any accesses to the output objects even mentioned.

然而,标准的措辞似乎表明,如果2个指针指向同一个对象,则该行为可能是意外的:转换结果放置在格式后的第一个参数所指向的对象中尚未收到转换结果的参数.这个短语有点模棱两可:尚未收到转换结果的指的是什么?对象还是参数?对象接收转换结果,而不是指针参数.在您的扭曲示例中,对象x已经收到了转换结果,因此它不应再接收到另一结果...但是,正如supercat所指出的那样,这种解释是限制性的,因为这暗示着所有转换后的值都将存储在第一个目标对象.

Yet the wording of the Standard seems to indicate that if 2 pointers point to the same object, the behavior might be unexpected: the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result. This phrase is somewhat ambiguous: what does that has not already received a conversion result refer to? the object or the argument? Objects receive conversion results, not the pointer arguments. In your contorted example, the object x has already received a conversion result, so it should not receive another one... But as noted by supercat, this interpretation is overtly restrictive as it would imply that all converted values be stored into the first target object.

因此,它似乎已完全指定并定义得很好,但是可以完善规范的措辞以消除潜在的歧义.

So it appears fully specified and well defined, but the wording of the specification could be perfected to remove a potential ambiguity.

这篇关于scanf(“%d%d",&amp; x,&amp; x)是否定义正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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