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

时间:2017-07-21 08:46:56

标签: c arrays string output codeblocks

我试图找出具有已知大小的字符串如何用单个字符填充。然后我为这个更大的问题编写了这个简单的代码  (动态填充未知大小的字符串) 。当我尝试编译并运行此代码时,我遇到了一个输出有心脏符号的问题!我不知道它来自哪里。

#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;
}

谢谢。

2 个答案:

答案 0 :(得分:3)

C strings是由null character终止的字符序列(即代码为0的字符)。它可以表示为'\0''\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()将返回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;
}

答案 1 :(得分:0)

c中的字符串需要以null结尾,因此您可能忘记在str的末尾添加<section id="skills"> <h3>skills</h3> <div> <div><img src="./img/python.png"> <h5>Python</h5> </div> <div><img src="./img/js.png"> <h5>Javascript</h5> </div> <div><img src="./img/vue.png"> <h5>Vue.js</h5> </div> <div><img src="./img/nodejs.png"> <h5>Node.js</h5> </div> <div><img src="./img/mongodb.png"> <h5>MongoDB</h5> </div> <div><img src="./img/express.png"> <h5>Express.js</h5> </div> <div><img src="./img/babel.png"> <h5>Babel.js</h5> </div> <div><img src="./img/npm.png"> <h5>NPM</h5> </div> <div><img src="./img/html.png"> <h5>HTML</h5> </div> <div><img src="./img/css.png"> <h5>CSS</h5> </div> <div><img src="./img/sass.png"> <h5>Sass</h5> </div> <div><img src="./img/boostrap.png"> <h5>Bootstrap</h5> </div> <div><img src="./img/jquery.png"> <h5>Jquery</h5> </div> <div><img src="./img/ajax.png"> <h5>Ajax</h5> </div> <div><img src="./img/restful.png"> <h5>RESTful</h5> </div> <div><img src="./img/heroku.png"> <h5>Heroku</h5> </div> </div> </section>字符。心脏符号显示的原因是当puts()尝试写出一个字符串时,它会一直读取内存中的下一个字符,直到它到达空终止符'\0'。因为它没有遇到它只是继续读入记忆并碰巧找到心脏符号我猜。希望这会有所帮助。