我知道您可以使用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
这同样适用于fputsVS 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-tempsgcc 的选项可以做到这一点
以我的经验,无论使用哪种格式的字符串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()。