2017-02-21 24 views
0

我已经使用了一个非常简单的代码:CZ中的%zd说明符是否为可选功能?

int main(void) 
{ 
    size_t variable; 
    /*prompt*/ 
    printf("enter the value of the variable: "); 
    scanf("%zd", &variable); 
    printf("you entered %zd value of the variable", variable); 
} 

Howeve,GCC编译器产生以下结果:

Enter the vale of the size_t variable: 15 
You entered zd value of size_t type 
Process returned 35 (0X23) execution time: 3.094s 
Press any key to continue 

我的书也证明了上述例子的情况下直接提的是,它是某种一个特殊的格式说明符,如果库文件被包含在内。 即使the online compiler也没有产生正确的结果。 为什么代码无法正常工作?

+0

因为您调用'printf'而不传递说明符的参数。 – StoryTeller

+0

如果你打开了更多的警告,你会发现你将'variable'的* value *而不是* address *传递给'scanf()'。 –

+1

[如何使用\“printf()\'?]使用”zd“说明符的可能的重复项(http://stackoverflow.com/questions/32916575/how-to-use-zd-specifier-with-printf) – Jayesh

回答

6
scanf("%zd", variable); 

是未定义的行为,因为您没有传递指针。

printf("you entered %zd value of the variable"); 

也是未定义的行为,因为您使用了格式说明符但未通过匹配参数。

%zd是C11托管实现的强制功能。这意味着任何实现stdio.h的编译器都是必需的。但是,%zd没有多大意义,因为size_t始终未签名。改为使用%zu

请注意,标准库的不兼容实现存在,最值得注意的是Microsoft的Windows实现。标准库的Microsoft实现由Visual Studio使用,也由gcc/mingw编译器使用。该库不适合%zu,因为它不符合C11标准。

+1

而这个问题的答案? _I是%zd说明符在C11中的可选功能吗?_ –

+0

@KeineLust,对不起,这是一个错字 – bzal

+0

@KeineLust更新。 – Lundin

2

Nopes,%zd是实现符合要求的格式说明符之一,它不是可选

引用C11,章§7.21.6.2,fscanf()

z用于指定后续diouxX,或n转换说明适用 到的参数与类型的指针到size_t或相应的签名 整数类型。

这就是说,在你的代码中,用法是错误的,有两个原因。

  1. 您需要传递一个指针类型作为所提供的转换说明符的参数。
  2. size_t被定义为无符号整数类型,因此您应该使用适当的格式说明符%zu而不是%zd

    再次引用C11第7章。19

    size_t

    这是sizeof操作的结果的无符号整数类型;

喜欢的东西

scanf("%zu", &variable); 

应该正常工作。

+0

您的观点2.由于OP在谈论'gcc' ......很高兴地说'%zd'显示它就好像它已被签名一样。 –

+0

@Sourav Ghosh,它仍然打印zd – bzal

+0

@Sourav Ghosh,http://pasteboard.co/BkhCHgjhM.png – bzal