为什么输出长度为6?

时间:2013-12-26 06:48:11

标签: c

我编写了一个简单的程序来以这种方式计算字符串的长度。 我知道还有其他方法。但我只是想知道为什么这个程序正在提供这个输出。

#include <stdio.h>
int main()
{
     char str[1];
     printf( "%d", printf("%s", gets(str)));

     return 0;
}

输出:

(null)6

5 个答案:

答案 0 :(得分:3)

除非你总是从标准输入传递空字符串,否则你正在调用未定义的行为,因此输出几乎可以是任何东西,并且它也可能崩溃。 str不能是格式正确的C字符串,超过零个字符。

char str[1]为一个单个字符分配存储空间,但该字符必须是NUL字符才能满足C字符串约束。您需要创建一个足够大的字符数组来保存您使用gets编写的字符串。

&#34;(空)6&#34;因为输出可能意味着gets返回NULL,因为它由于某种原因失败或者堆栈被损坏,使得返回值被零覆盖(根据未定义的行为解释)。 6以下&#34;(null)&#34;是预期的,因为printf的返回值是打印的字符数,&#34;(null)&#34;是六个字符长。

答案 1 :(得分:1)

它调用未定义的行为。在这种情况下,你可能得到任何东西。如果您没有传递空字符串,则至少str应为2个字节。

答案 2 :(得分:1)

您的计划存在一些问题。

首先,你将char缓冲区定义得太短,一个字符串的1个字符串缓冲区只能容纳一个字符串,空字符串。这是因为您需要在字符串末尾使用null来终止它。

接下来,您正在使用非常不安全的gets函数(因为您的编译器几乎肯定会警告您),因为它只是盲目地接受输入并将其复制到缓冲区中。由于您的缓冲区长度为0 +终止符,您将自动将字符串的末尾覆盖到其他内存区域,这些区域可能并且可能包含重要信息,例如rsp(您的返回指针) 。这是粉碎堆栈的经典方法。

第三,您将printf函数的输出传递给另一个printfprintf不是为格式化字符串和返回字符串而设计的,还有其他功能。通常,您要使用的是sprintf并将其传递给字符串。

请阅读有关此类事情的文档,如果您在尝试编程之前不确定是否有任何特定内容,请阅读。您似乎对许多重要C函数的基本用法感到困惑。

答案 3 :(得分:0)

声明变量时,会保留一些空间来存储值。 保留空间可以是以前由其他人使用的空间 代码并具有价值。当变量超出范围或free d时 该值不被删除(或者可能是,任何事情都可以。)只有程序才能访问 该变量被撤销。

当你从一个单一的位置读取时,你可以得到任何东西。

这是未定义的行为,你正在这样做,

gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3上的输出为0

答案 4 :(得分:0)

对于上面的程序,你的输入是“(null)”,所以你得到“(null)6”。这里“6”是printf的输出(成功打印的字符数)。