printf(string)与printf(“%s”,string)

时间:2012-12-03 21:30:04

标签: c printf

我正在编写一个代理服务器,我遇到了一个奇怪的错误,我希望有人可以解释。

我收到了客户端GET请求的第一行。例如,客户端将发送请求:

GET http://en.wikipedia.org/wiki/Special:Random HTTP/1.0
Host: en.wikipedia.org
...

我会将此请求转发给服务器。

但是,对于某些网址,我会遇到一个问题:

GET http://map.media6degrees.com/orbserv/curl=http%3A%2F%2Fwww.masteringemacs.org%2Farticles[trunc] HTTP/1.0

我将此行读入char buffer[MAXLINE_LENGTH],该行足以容纳字符串。

当我用

打印收到的获取请求时
printf(buffer);

打印的字符串是:

GET http://map.media6degrees.com/orbserv/hbpix?pixId=2869&curl=http0X0.0000000000015P-10220.0000000.000000www.masteringemacs.org0.000000articles0.00000020100.000000110.000000010.000000running-shells-in-emacs-overview204741995430849962482228271154502456423284733956118041206315879167624419264810411254941012469231829496710329852458403099883653794777355548418601638730167027236864.000000 HTTP/1.0

看来%3A,%2F等已经过字符串格式化。

当我运行printf("%s", buffer);时,我得到了正确的预期输出

编辑:我明白为什么会这样;我对为什么会这样发生感兴趣。 printf的值是来自堆栈中某个任意区域的“字符串格式”吗? %3A等有效格式字符串吗?

4 个答案:

答案 0 :(得分:7)

1)如果你看一下函数原型,你会看到printf()需要一个格式字符串,以及零个或多个参数。因此,严格来说,“printf(string)”正确:

SYNOPSIS
       #include <stdio.h>

       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
       int sprintf(char *str, const char *format, ...);
       int snprintf(char *str, size_t size, const  char  *format,
       ...);

2)第一个参数解释为格式字符串,它找到的任何“%XXX”条目将被解释为占位符。这听起来正是发生了什么:)

3)解决方案当然是printf ("%s", string)

4)或者使用puts(string)代替:)

答案 1 :(得分:5)

切勿将输入字符串用作printf的格式参数。

要正常工作,它必须没有“%...”项。这些是printf()函数访问参数列表的特殊命令。

答案 2 :(得分:1)

formatprintf系列函数scanf的{​​{1}}参数中,%被视为转义字符。您的原始输入包含其中一些,而printf正试图解释它们。

答案 3 :(得分:0)

如果使用printf(string),则打印的字符串可能为NULL 这是我看到的唯一问题.printf函数根据提供的格式读取所有va_list参数,因此如果传递NULL指针它可能会崩溃。 使用LLVM 4.1,我收到此警告:

Format string is not a literal string (potentially insecure)

这是我个人的观点:如果你确定该字符串不是NULL(可能通过断言验证它,然后在发布中删除该断言),那么你可以使用printf(string)。如果你不完全确定字符串可能为NULL或无效,然后使用文字字符串。