简体   繁体   English

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

Why the compiler gives me the error "too many arguments for format" when I use the specifier F in CodeBlocks?当我在 CodeBlocks 中使用说明符 F 时,为什么编译器会给我错误“太多 arguments 格式”?

#include <stdio.h>

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

The errors:错误:

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

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

Looks like some versions of GCC don't recognize %F , oddly enough.看起来有些版本的 GCC 无法识别%F ,这很奇怪。 My gcc version 9.2.0 (tdm64-1) for windows with C11 standard, does not recognize it though it only issues those as warning messages not errors.我的gcc version 9.2.0 (tdm64-1)用于 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);
      |            ^~~~~~

Upon execution the value is not printed.执行时不打印该值。

I'm guessing you might be using some mingW installation in a Windows system and your compiler must be treating warnings as errors, which is not a bad idea.我猜您可能在 Windows 系统中使用了一些 mingW 安装,并且您的编译器必须将警告视为错误,这不是一个坏主意。

As @HolyBlackCat suggested , adding -D__USE_MINGW_ANSI_STDIO flag solves the issue.正如@HolyBlackCat 建议的那样,添加-D__USE_MINGW_ANSI_STDIO标志可以解决问题。

This thread has the instructions on how to do it.这个线程有关于如何做的说明。

@RobertS supports Monica Cellio answer has a link with instructions on how to add it to CodeBlocks. @RobertS 支持 Monica Cellio 答案有一个链接,其中包含有关如何将其添加到 CodeBlocks 的说明。

Alternatively, for a quick fix of the code you can use %G , or %E for scientific notation.或者,为了快速修复代码,您可以使用%G%E作为科学记数法。

The F format specifier was first introduced in C99. F格式说明符最初是在 C99 中引入的。 Your compiler either seems to be compliant to C89/C90 or the std=c90 / std=c89 compiler option is enabled.您的编译器似乎与 C89/C90 兼容,或者启用了std=c90 / std=c89编译器选项。

If you configured compiler is gcc, you can use the gcc --version command to detect the version.如果你配置的编译器是 gcc,你可以使用gcc --version命令来检测版本。

Else you should check the set compiler options for which standard the compiler uses.否则,您应该检查编译器使用的标准的设置编译器选项。 Take a look at here:看看这里:

How to add compiler flags on codeblocks 如何在代码块上添加编译器标志

Although for Ubuntu (I don´t know on what OS you are using CodeBlocks), but this answer gives you an visual overview of the set up for compiler options in CodeBlocks.尽管对于 Ubuntu (我不知道您在什么操作系统上使用 CodeBlocks),但答案为您提供了 CodeBlocks 中编译器选项设置的直观概述。

The compiler gives you the error "too many parameters for printf" because it doesn't recognize %F as a format specifier.... so the parameter you have added to printf() is extra , and should not be there.编译器为您提供错误“printf 的参数过多”,因为它无法将%F识别为格式说明符......所以您添加到printf()的参数是额外的,不应该存在。

The standard format specifiers from C89 below, specify that the floating point formats are e , E , f , g and G (does not include F , the reason is stated in the last edit of this answer)以下C89的标准格式说明符指定浮点格式为eEfgG (不包括F ,原因在此答案的最后编辑中说明)

Remember that the compiler shouldn't read the format string of printf() at all to match the parameters with the format specifiers, so what is happening there should only deal with the printf(3) specification, and that is indeed an issue for printf(3) not for the compiler.请记住,编译器根本不应该读取printf()的格式字符串以将参数与格式说明符匹配,所以那里发生的事情应该只处理printf(3)规范,这确实是printf(3)的问题printf(3)不适用于编译器。 Probably if you try the generated program it should work.可能如果您尝试生成的程序,它应该可以工作。

EDIT编辑

I have tried on clang (sorry, but I have no gcc here) and I have discovered some possible cause of the issue (not an error, either).我已经尝试过 clang(抱歉,我这里没有 gcc)并且我发现了一些可能的问题原因(也不是错误)。 The printf(3) implementation here, does never switch to scientific notation at all (which is something I have not checked with the standard) so it is never going to generate an alphabetic character and no lowercase or uppercase letter is concerned.这里的printf(3)实现根本不会切换到科学记数法(这是我没有用标准检查过的东西),所以它永远不会生成字母字符,也不关心小写或大写字母。 So for the program所以对于程序

#include <stdio.h>

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

it prints:它打印:

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

while for而对于

#include <stdio.h>

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

it prints它打印

$ a.out
31415926539999999255132844331312943389972993386142531366742209094398699375217155068328829400434148008839629239544769533043070670437328460352417427610347451187200.000
$ _

As only digits and decimal point are emitted, there's no uppercase or lowercase interpretation on the case of the format specifier, making both forms equivalent (but one being nonstandard).由于仅发出数字和小数点,格式说明符的大小写没有大写或小写解释,使得 forms 等效(但一个是非标准的)。

The solution is just to switch to lowercase f .解决方案只是切换到小写f

As @chux-ReinstateMonica suggests in one of the comments, C89 , page 133 (143 of the pdf), the standard doesn't include the F format specifier, only e , E , f , g and G .正如@chux-ReinstateMonica 在评论之一中建议的那样, C89 ,第 133 页(pdf 的 143 页),该标准不包括F格式说明符,只有eEfgG This should be normal, considering that f never changes to exponential notation.这应该是正常的,考虑到f永远不会更改为指数符号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM