我刚开始学习C,因为我混合了scanf和printf,我不小心写了这样的代码:
float loan = 0.0f; // loan
float rate = 0.0f; // monthly interest rate
float mpay = 0.0f; // monthly pay
printf("Enter amount of loan: ");
scanf("%.2f",&loan); // I am supposed to write scanf("%f",&loan), I was trying to take a float input with two digits after point
printf("Enter interest rate: ");
scanf("%.2f",&rate); // similar here
printf("Enter monthly payment: ");
scanf("%.2f",&mpay); // similar here
我希望这段代码会显示三个输入提示,每个提示都会挂起并等待,直到我键入一些输入并按Enter键。但是发生的事情是,只有第一个提示正在等待我的输入,然后当我点击输入时,第二个和第三个提示快速显示而不等待我的输入,好像代码从其他地方获得我的输入。后来当我检查了三个应该保存三个输入的变量的值时,它们都没有实际存储输入值。
我回到我的C书并意识到我将printf
的最小字段和精度参数概念与scanf
混合在一起,所以我猜扫描会有这样的语法吗?但如果是这样,那么为什么编译器会编译,这是不是意味着scanf也有这样的语法,或者我错了吗?我应该如何解释这种不等待我的第二和第三个输入,而不是将输入存储到三个变量中的奇怪行为?
答案 0 :(得分:3)
是的,C标准规定的scanf()
系列并不支持此功能。它显式未定义的行为,这意味着允许发生任何。
但是一些编译器确实实现了一个警告,它在编译时检查格式字符串的有效性。 GCC(和Clang)有-Wformat
(由-Wall
启用,无论如何都应该使用)。如果您使用的是其他编译器,则必须阅读其文档或使用静态分析工具。
来自ISO C11委员会草案(N1570),7.21.6.2第13段:
如果转换规范无效,则行为未定义。 287)
脚注是指7.31.11的标准杆。 1:
可以将小写字母添加到fprintf和fscanf中的转换说明符和长度修饰符。其他字符可用于扩展名。
所以.
实施可以支持scanf()
作为扩展程序,但我并不知道有一个。[/ p>
答案 1 :(得分:1)
在TC上运行此代码,并按照您的说法执行... 首先,您不应在scanf中包含字段格式说明符。
在我的情况下,我认为,除了%f之外你提供的数字(在你的情况下就像.2)..因为scanf表现异常......你提供的输入值可能会被存储在不同的地址位置(与2相关的东西)..所以变量率,贷款等没有显示值,因为没有任何内容存储在其中。
答案 2 :(得分:0)
您无法转换scanf
中的精度。如果您使用gcc
进行编译,则应收到unknown conversion type character ‘.’ in format
警告。
检查程序的一种方法是打印出scanf
的返回值,你会发现所有这3个scanf
都给你0,这意味着3个变量中没有一个被扫描过任何值英寸