在将整数转换为C中的字符串时,我对包含stdio.h
感到有些恼火 - 不会用不必要的文件描述符和其他代码来破坏二进制文件吗?或者只有在代码中使用标准的io文件描述符stdout,stdin或stderr时才会打开流,例如printf
,scanf
,fprintf
?如果我的代码只使用snprintf(3)
?
我最接近的现成解决方案是将整数转换为strfromd(3)
的双精度浮点,格式字符串不会打印小数点。
bhuwansahni 在How to convert integer to string in C?中提供了一个很好的自助解决方案
我看不到如何使用(链接不起作用)itoa
,_itoa
或_fitoa_word
,尽管_fitoa_word
确实显示为nm /lib64/libc6.so.6
的函数{1}}。
答案 0 :(得分:5)
即使您不包含stdio.h
,也会打开它们。它们是程序的标准流,并在运行时打开。
程序在实际执行之前需要进行一些初始化。这包括加载符号表,分配内存,初始化静态数据和链接动态库等。此时打开标准流。然后控件转到程序中的main()
函数并开始执行。
对于第二个问题,标准IO不会使程序膨胀,因为您的程序几乎总是与标准C库libc
链接,并且通常是动态链接的(因此它不会增加大小你的可执行文件)。
是的,如果你不使用它们就没问题。只使用像snprintf()
这样的东西,你可以做得很好,但标准流仍然会被打开。使用它们与否并不重要。
谢谢 Paul Ogilvie
答案 1 :(得分:0)
我对包含stdio.h感到有些恼火 - 不会用不必要的文件描述符和其他代码来破坏二进制文件吗?
没有。链接C运行时会增加您的代码,但如果没有它,您将无法做很多事情。此运行时包含启动代码,以确保标准流可用。在许多系统上,新启动的进程已经从一开始就获取了相应的打开文件,可能是由父进程继承的。
答案 2 :(得分:0)
实际上,在加载可执行文件之前,这些流甚至会打开。这就是通常发生的事情:
有些shell会解析一个命令,告诉它执行你的程序。此命令可能包括stdin
,stdout
和`stderr的重定向。
shell调用fork()
来创建一个新进程。该新进程仍在运行shell代码。
新进程中的shell代码按照已解析的重定向规定打开输入/输出流。如果你说2>/dev/null
,它会打开/dev/null
作为文件描述符2
。
分叉的shell代码调用exec()
,以控制代码。
当您的代码写入stdout
时,它只会写入已打开的文件描述符2
。
您可以看到,文件描述符0
,1
和2
的解释只是将打开的文件描述符传递给进程的约定。您可以指示shell打开更多文件描述符5>myCoolStream
,或关闭现有文件描述符。如果是这样,您的流程期望什么,那很好。如果您的流程需要其他内容,那就是您的问题。
因此,除了为<stdio.h>
等提供通常的函数原型和类型定义之外,是否包含printf()
没有任何效果。流本身完全不受此影响。