为什么我的代码不适用于我的 VS 代码和代码块?

Why my code doesn't work with my VS Code, and Code Blocks?

我写了下面的C程序:

#include <stdio.h>

int main()
{
    char d;
    char e;
    printf("Babanin adini gir. \n");
    scanf("%s", &d);
    printf("Ananin adini gir. \n");
    scanf("%s", &e);
    printf("Senin adin %c ya da %c", d, e);
return 0;

}

它在在线 C 编译器中工作得很好,但在我的 VSCode 或 Codeblocks 中却不行,它只说

Gimme a letter. 
s
Gimme another letter. 
a
Your letter is  or a

像那样,它不读取第一个字母或打印它。 这是为什么?

当您说 char d; 时,您告诉编译器恰好保留一个字节的内存来保存一个字符。

然后当你说 char e; 时,你告诉编译器只保留一个字节的内存来保存另一个字符。

然后你说 scanf("%s", &d); 让编译器读取整个字符串(包括字符串终止符)并尝试将其存储在 char d;

保留的一个字节内存中

你输入的字符 运行 程序占用 space 的一个字节,字符串终止符占用另一个字节,所以现在你将两个字节的数据存储在一个只够大的地方一个字节。

然后为第二次 scanf 调用再次执行此操作。

所以现在您已经访问了您没有保留的内存 - 您可能已经覆盖了一些非常重要的东西。这是未定义的行为,任何事情都可能发生(包括使程序看起来好像在运行)

因此,如果您想像现在这样使用 char 变量,scanf("%s", &d); 应该是 scanf(" %c", &d); 并且其他 scanf 调用应该以相同的方式更改。

scanf 格式字符串需要以 space 开头的原因是告诉 scanf 函数它应该忽略 whitespace(就像换行符一样通过按回车键创建)。如果没有 space,第二个 scanf 将存储换行符作为其字符,因为这是输入的第二个字符。

您可能认为您还可以将变量更改为 char d[2];char e[2];,以便有空间存储字符和字符串终止符。但这是一个坏主意,因为如果用户在按下回车键之前输入了多个字符,您仍然会写到内存末尾。所以它有完全相同的问题。

您可以做的另一件事(如评论中所建议的那样)是根本不使用 scanf 来读取单个字符。如果您的变量是 char d; 那么您可以使用 d = getchar(); 并且效果很好 - 但您仍然需要做一些事情来处理作为第二个字符出现的换行符。这就是为什么我认为 scanf(" %c", &d); 是使其工作的好、简单的方法。

还有一件事要注意:您应该始终检查所调用函数的 return 值。如果读取输入不起作用,您应该告诉用户输入无效,然后不要产生无效输出。

Jerry Jeremiah 的回答很好,但我只想补充一点,如果他的解决方案对您不起作用,您可能需要使用“%c”(带前导 space)而不是“%c”或第二个 scanf 将换行而不是第二个字母。

参考这个帖子:How to do scanf for single char in C