为什么 puts() 函数会给我一个心形符号?

Why does puts() function gives me a heart symbol?

我试图弄清楚如何用单个字符填充已知大小的字符串。然后我写了这个简单的代码来解决我遇到的一个更大的问题 (动态填充未知大小的字符串) .当我尝试编译和 运行 这段代码时,我遇到了输出有一个心形符号的问题!而且我不知道它来自哪里。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    char str[3];
    for(i=0;i<=2;i++){
        str[i]=getc(stdin);
    }
    puts(str);
    return 0;
}

谢谢。

c 中的字符串需要以 null 结尾,所以可能是您忘记在 str 的末尾添加 '[=10=]' 字符。心形符号出现的原因是,当 puts() 尝试写出一个字符串时,它会不断读取内存中的下一个字符,直到到达空终止符 '[=10=]'。由于它没有遇到它,它只是继续读入内存并恰好找到我猜的心形符号。希望这有帮助。

C strings are sequences of chars terminated by the null character(即代码为0的字符)。它可以表示为 '[=15=]''\x0' 或简单地表示为 0.

您的代码用三个字符填充 str,但未能生成 null 终止符。因此,puts() 打印它在内存中找到的任何字符,直到它到达第一个 null 字符。

您的代码暴露了 Undefined Behaviour。它可以做任何事情,这不是它的错。

为了修复它,您必须确保字符串以 null 终止字符结尾:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    // Make room for 3 useful chars and the null terminator
    char str[4];
    // Read three chars
    for(i = 0; i < 3; i ++) {
        str[i] = getc(stdin);
    }
    // Add the null terminator for strings
    str[3] = 0;

    puts(str);
    return 0;
}

更新

正如@JeremyP 在评论中指出的那样,如果您从 (stdin) 读取的文件在代码读取 3 个字符之前结束,fgetc() 将 return EOF(文件结尾)字符也是有趣的不可打印字符,让您想知道它们来自哪里。

编写此代码的正确方法是在读取输入文件之前检查输入文件是否到达其 EOF (feof()):

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    // Make room for 3 useful chars and the null terminator
    char str[4];
    // Read at most three chars
    for(i = 0; i < 3 && !feof(stdin); i ++) {
        str[i] = getc(stdin);
    }
    // Add the null terminator for strings
    str[i] = 0;

    puts(str);
    return 0;
}