C 为什么用%s打印字符*(空)?

C 为什么用%s打印字符*(空)?,c,C,这是我的代码: char *x; char *y; printf("x:"); scanf("%s", x); printf("y:"); scanf("%s", y); printf("x: %s, y: %s\n", x, y); return 0; 当我运行它时: x:hello y:world x: hello, y: (null) 为什么我是空的而不是世界 感谢您的帮助您从不

这是我的代码:

char *x;
char *y;

printf("x:");
scanf("%s", x);

printf("y:");
scanf("%s", y);

printf("x: %s, y: %s\n", x, y);
return 0;
当我运行它时:

x:hello 
y:world
x: hello, y: (null)
为什么我是空的而不是世界


感谢您的帮助

您从不为字符串分配空间。它们指向一些随机的垃圾值。 使用malloc为字符串动态分配空间,或使用char[]进行自动存储

下面是一个自动分配空间的示例:

#include <stdio.h>
#include <stdlib.h>
int main() {
    char x[20]; // space for 19 characters and a null-terminator
    char y[20];

    printf("x:");
    scanf("%s", x);

    printf("y:");
    scanf("%s", y);
    printf("x: %s, y: %s\n", x, y);
    return 0;
}
为什么用%s打印字符*会打印“空”

为了回答为什么会得到空值的问题,我猜您使用的是glibc

。例如,这将打印hello null:

char *a = "hello", *b = NULL;
printf("%s %s\n", a, b);
然后,如果您再次尝试以下操作:

printf("%s\n", b);
,它不做同样的事情,但很高兴地访问指针,通常会崩溃,这没关系,因为实际上,将NULL传递给printf是错误的,而且无论如何,它可能不适用于其他C库

另外,如果您要检查scanf调用的返回值,您会看到第二个调用返回0,这表明它无法完成转换。当将空指针作为%s的目标传递时,glibc的scanf似乎就是这样做的。嗯,不管怎么说,这就是它看起来的样子,我在手册中没有找到。再说一次,不要指望它

那么为什么y中有空指针呢?因为你没有初始化它,这就是你碰巧得到的值。当然,这样做时,行为是完全未定义的,但在本例中,行为似乎与您执行char*y=NULL时得到的结果相匹配;相反


关于你应该做什么,已经有了一个很好的答案,所以我不会去那里。

你从来没有为x或y分配过任何空间,所以它们是未定义的。该行为未指明。您的scanf调用正在写入x和y中的未知内存位置。它可以是任何东西。您尚未为*x或*y分配任何内存,scanf不会为您分配内存。代码具有未定义的行为。MS编译器善意地打印空值,但有些会让程序崩溃。对于未定义的行为,结果甚至不一致。char*x->char x[100]。使用malloc分配小型固定大小的缓冲区是过度的。这就是为什么我说他可以使用char[]的原因。你应该坚持认为malloc在这里是个坏主意,这是一个坏做法。否则,初学者可能会认为他们实际上应该使用malloc-likethat@Jabberwocky编辑此代码将具有强大的缓冲区溢出保护:scanf%19s,x;有19个字符的空格,而不是20个。