【问题标题】:What happens when a format specifier is not given to printf?当 printf 没有指定格式说明符时会发生什么?
【发布时间】:2014-01-26 22:52:03
【问题描述】:

我在 Careercup 中遇到过这个关于 printf 的问题。

char *str = "hello";
printf("%s",str);
printf(str);

第二个 printf 语句有时会崩溃。我检查了各种网站。编写程序,看看它是否确实如此。但事实并非如此。另外,我知道 printf 接受类型为“const char* format”的参数,但格式可以是任何常量字符串,如“hello”。但是如果我将它存储在一个字符串 str 中(它当然指向只读内存)。预计将以相同的方式工作。究竟会发生什么?

谁能给个详细的解释。

【问题讨论】:

  • 它的工作方式完全相同。第一个参数始终被解释为格式字符串。
  • str 变量不包含%something 占位符...
  • 我看不到第二条语句会如何崩溃,除非 str 不是以 null 终止的。
  • @cup 如果第二个语句包含参数说明符,则它可能会崩溃,因为没有参数。

标签: c string


【解决方案1】:

格式字符串中的格式说明符不是必需的,因此:

printf("%s", "Hello world\n");

printf("Hello world\n");

将产生相同的行为。

但是如果字符串在:

printf(str);

来自用户输入,您应该使用%s 说明符,否则您很容易受到格式化字符串攻击(攻击者可以使用%x 伪造字符串来转储堆栈,使用%n 来覆盖内存)。

【讨论】:

    【解决方案2】:

    使用动态格式字符串调用printf 一般是不安全的:

    void foo(char const * p)
    {
        printf(p);   // !
    }
    

    您无法仅从程序源代码判断程序是否正确。正确性取决于字符串的(即它不能包含格式说明符),它可能是未定义的行为。

    这是该语言的不安全方面之一:您正在放弃类型系统(因为变量参数),因此您放弃了静态正确性可验证性。

    从字面上打印字符串的安全方法是fputs(p, stdout),或者(可能效率较低)printf("%s", p)

    【讨论】:

      【解决方案3】:
      char *str = "hello";
      printf(str);
      

      相当于:

      printf("hello");
      

      就像:

      char *format = "%s",
           *str = "hello";
      printf(format, str);
      

      相当于:

      char *str = "hello";
      printf("%s",str);
      

      ...而你能否真正依赖format的内容是完全不同的故事。

      【讨论】:

        猜你喜欢
        • 2013-05-27
        • 2013-06-22
        • 2013-06-22
        • 2015-12-07
        • 2012-05-17
        • 2012-05-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多