我知道您可以使用printf()
和打印puts()
。我还可以看到,它printf()
允许您插值变量并进行格式化。
是否puts()
仅仅是一种原始的版本printf()
。是否应将其用于printf()
没有字符串插值的所有可能?
printf(variable)
打印字符串。使用puts(variable)
或printf("%s', variable)
。使用变量格式字符串存在安全风险:如果变量可以由攻击者编写,则他们可以使用格式字符串来攻击程序。
我知道您可以使用printf()
和打印puts()
。我还可以看到,它printf()
允许您插值变量并进行格式化。
是否puts()
仅仅是一种原始的版本printf()
。是否应将其用于printf()
没有字符串插值的所有可能?
printf(variable)
打印字符串。使用puts(variable)
或printf("%s', variable)
。使用变量格式字符串存在安全风险:如果变量可以由攻击者编写,则他们可以使用格式字符串来攻击程序。
Answers:
puts
比简单,printf
但请注意,前者会自动添加换行符。如果这不是您想要的,则可以fputs
将字符串输出到stdout或使用printf
。
(Zan Lynx在评论中指出了这一点,但我认为值得一提-因为公认的答案没有提及它)。
puts(mystr);
和之间的本质区别在于,printf(mystr);
后者将参数解释为格式字符串。其结果将是往往是相同的(除了加入新行),如果字符串不包含任何控制字符(%
),但如果你不能依赖于(如果mystr
是一个变量,而不是文字),你应该 不使用它。
因此,将动态字符串作为单个参数传递通常是危险的-从概念上讲是错误的printf
:
char * myMessage;
// ... myMessage gets assigned at runtime, unpredictable content
printf(myMessage); // <--- WRONG! (what if myMessage contains a '%' char?)
puts(myMessage); // ok
printf("%s\n",myMessage); // ok, equivalent to the previous, perhaps less efficient
这同样适用于fputs
VS fprintf
(但fputs
不会添加新行)。
printf()
效率较低?在运行时?在编译时?
printf
需要解析格式字符串。但是,这通常是无关紧要的。此外,一个聪明的编译器可以优化这一点,并更换printf
与调用puts
在简单的情况下,编译器会将调用转换printf()
为puts()
。
例如,以下代码将编译为我接下来显示的汇编代码。
#include <stdio.h>
main() {
printf("Hello world!");
return 0;
}
push rbp
mov rbp,rsp
mov edi,str.Helloworld!
call dword imp.puts
mov eax,0x0
pop rbp
ret
在此示例中,我使用了GCC版本4.7.2,并使用编译了源代码gcc -o hello hello.c
。
printf("Hello world!\n");
gcc确实应该将其转换为puts。由于这是旧消息,因此我将自己对其进行编辑。
-save-temps
gcc 的选项可以做到这一点
以我的经验,无论使用哪种格式的字符串printf()
,都可以处理更多的代码puts()
。
如果不需要格式,则不要使用printf
。然而,fwrite
到stdout
作品很多比快puts
。
static const char my_text[] = "Using fwrite.\n";
fwrite(my_text, 1, sizeof(my_text) - sizeof('\0'), stdout);
注意:每个注释中的'\ 0'是一个整数常量。正确的表达应sizeof(char)
如注释所示。
'\0'
具有类型int
,因此在大多数系统上都会打印Using fwrit
。如果你想打印少1个字节,只使用1 sizeof (char)
,这很可能是你在这里有什么目的,是保证为1
int puts(const char *s);
puts()将字符串s和尾随换行符写入stdout。
int printf(const char *format, ...);
函数printf()在格式字符串的控制下将输出写入stdout,该格式字符串指定如何转换后续参数以输出。
我将借此机会请您阅读文档。
printf()函数用于在屏幕上同时打印字符串和变量,而puts()函数仅允许您仅在屏幕上打印字符串。
puts
是简单的选择,并在末尾添加新行,并printf
写入格式化字符串的输出。
我建议仅使用printf
此方法,因为它比切换方法更一致,即,如果您正在使用debbugg,则搜索所有printfs的痛苦会小于puts
和printf
。多数情况下,您也希望在打印输出中输出变量,因此puts
通常在示例代码中使用。
比较puts()
和时printf()
,即使它们的内存消耗几乎相同,puts()
也比花费更多时间printf()
。