为什么会发生这种情况(见图)?

时间:2008-11-13 17:26:17

标签: c console terminal reset

为什么以下操作会产生这样的效果 - 它会打印一个充满随机字符的终端,然后退出时会留下一个命令提示符,当您键入它时会产生垃圾。 (我试过它,因为我认为它会产生一个段错误。)

http://oi38.tinypic.com/r9qxbt.jpg

#include <stdio.h>

int main(){
    char* s = "lololololololol";
    while(1){
        printf("%c", *s);
        s++;
    }
}

它编译为:

gcc -std=c99 hello.c

7 个答案:

答案 0 :(得分:20)

它最终会出现故障,但在此之前它会打印出同一页面中的任何字节。这就是你在屏幕上看到随机字符的原因。

那些可能包含转义序列来改变(比方说)控制台的字符编码。这就是为什么你在退出后输入控制台时最终会出现乱码的原因。

答案 1 :(得分:7)

您只是打印出内存中的内容,因为您的循环不会停留在字符串的末尾。每个随机字节都被解释为一个字符。当你到达记忆页面的末尾(进入不可读的区域)时,它会出现故障。

答案 2 :(得分:7)

因为你有一个无限循环(while(1)),并且你不断得到指针(*s)的当前值,然后将指针向前移动一个字符(s++)。这样就可以很好地超越字符串的末尾,进入“垃圾”(未初始化的内存),结果将其打印到控制台。

答案 3 :(得分:7)

除了其他所有人都说你忽略字符串终端字符并且只是打印内存超过字符串的内存时,你的命令提示符也是“垃圾”的原因是通过打印特定的“不可打印的“字符,你的终端会话处于一个奇怪的字符模式。 (我不知道它是哪个角色或者它改变了什么模式,但是也许其他人可以了解它比我知道得更好。)

答案 4 :(得分:2)

在这里给出的答案(这些都很优秀)稍微扩大了......当我刚刚开始使用C时,我不止一次地遇到这个问题,这是一个容易犯的错误。

while循环进行快速调整即可解决问题。其他人都给了你原因,我会告诉你如何:

#include <stdio.h>

int main() {
    char *s = "lolololololololol";
    while (*s != '\0') {
        printf("%c", *s);
        s++;
    }
}

请注意,我们正在进行循环检查而不是无限循环(while(1)),以确保我们提取的指针不是字符串的空终止符,从而避免溢出'遇到了。

如果你绝对需要while(1)(例如,如果这是家庭作业并且教师希望你使用它),请使用break关键字退出循环。以下代码闻起来,至少对我来说,但它起作用:

#include <stdio.h>

int main() {
    char *s = "lolololololololol";
    while (1) {
        if (*s == '\0')
            break;
        printf("%c", *s);
        s++;
    }
}

两者都产生相同的控制台输出,最后没有换行符:

  

lolololololololol

答案 5 :(得分:1)

你的循环没有终止,所以println会在你写的文字后打印内存中的内容;最终它将访问不允许读取的内存,导致它发生段错误。

您可以像其他人建议的那样更改循环,或者您可以利用以下事实:在零中,零为false并且null(终止所有字符串)也为零,因此您可以将循环构造为:

while (*s) {

而不是:

while (*s != '\0')

第一个可能更难以理解,但它确实具有简洁的优点,因此它通常用于节省一些打字。

答案 6 :(得分:0)

此外,您通常可以使用'reset'命令返回命令提示符,当然是盲目输入。 (输入Enter,reset,Enter)