printf("%f",x) ok, printf("%F",x) error too many arguments for format

printf("%f",x) ok, printf("%F",x) error too many arguments for format

当我在 CodeBlocks 中使用说明符 F 时,为什么编译器给我错误 "too many arguments for format"?

#include <stdio.h>

int main()
{
    float x = 3.14159;
    printf("%f\n", x);
    printf("%F\n", x);
    return 0;
}

错误:

error: unknown conversion type character 'F' in format [-Werror=format=]

error: too many arguments for format [-Werror=format-extra-args]

F 格式说明符首次在 C99 中引入。您的编译器似乎符合 C89/C90 或启用了 std=c90/std=c89 编译器选项。

如果你配置的编译器是gcc,你可以使用gcc --version命令检测版本。

否则,您应该检查编译器使用的标准设置编译器选项。看这里:

How to add compiler flags on codeblocks

虽然对于 Ubuntu(我不知道 OS 你在用什么 CodeBlocks),但是 this 答案给了你一个编译器选项设置的视觉概览在代码块中。

看起来有些版本的 GCC 无法识别 %F,很奇怪。我的 gcc version 9.2.0 (tdm64-1) for windows 使用 C11 标准,无法识别它,尽管它只发出警告消息而不是错误消息。

$ gcc main2.c -Wextra -Wall -pedantic -std=c11
main2.c: In function 'main':
main2.c:7:14: warning: unknown conversion type character 'F' in format [-Wformat=]
    7 |     printf("%F\n", x);
      |              ^
main2.c:7:12: warning: too many arguments for format [-Wformat-extra-args]
    7 |     printf("%F\n", x);
      |            ^~~~~~

执行时不打印值。

我猜您可能在 Windows 系统中使用了一些 mingW 安装,您的编译器必须将警告视为错误,这不是一个坏主意。

作为,添加-D__USE_MINGW_ANSI_STDIO标志解决了问题。

有操作说明。

有一个 link 以及如何将其添加到 CodeBlocks 的说明。

或者,为了快速修复代码,您可以使用 %G%E 作为科学记数法。

编译器给你错误 "too many parameters for printf" 因为它不能将 %F 识别为格式说明符....所以你添加到 printf() 的参数是 extra,不应该存在。

来自下面C89的标准格式说明符,指定浮点格式为eEfgG(不包括F,原因在此答案的最后编辑中说明)

请记住,编译器根本不应该读取 printf() 的格式字符串来匹配参数与格式说明符,所以那里发生的事情 应该只处理 printf(3) 规范,这确实是 printf(3) 的问题,而不是编译器的问题。如果您尝试生成的程序,它应该可以工作。

编辑

我试过 clang(抱歉,我这里没有 gcc),我发现了一些可能的问题原因(也不是错误)。这里的 printf(3) 实现根本不会切换到科学记数法(这是我没有用标准检查过的东西)所以它永远不会生成字母字符并且不涉及小写或大写字母。所以对于程序

#include <stdio.h>

int main()
{
        printf("%5.3G\n", 3.141592654E160);
}

它打印:

$ ./a.out
3.14E+160
$ _

而对于

#include <stdio.h>

int main()
{
        printf("%5.3F\n", 3.141592654E160);
}

它打印

$ a.out
31415926539999999255132844331312943389972993386142531366742209094398699375217155068328829400434148008839629239544769533043070670437328460352417427610347451187200.000
$ _

由于仅发出数字和小数点,因此格式说明符的大小写没有大写或小写解释,这使得两种形式等效(但有一种是非标准形式)。

解决办法就是改成小写f

正如@chux-ReinstateMonica 在评论之一 C89,第 133 页(pdf 的 143)中所建议的那样,该标准不包含 F 格式说明符,仅包含 eEfgG。这应该是正常的,考虑到 f 永远不会更改为指数表示法。