打印输入的字符时,getchar / putchar返回带有问号的框

时间:2019-02-05 08:30:25

标签: c character-encoding codeblocks

在Windows 10(丹麦语)的代码块中试用K&R的代码示例。下面的示例按预期工作:

#include <stdio.h>

int main() {
    char c = 'a';
    putchar(c);
}

但是,以下内容会打印一系列带有问号的框,这些框与我键入的字符数相同:

#include <stdio.h>

int main() {
    char c;

    while (c = getchar() != '\n') {
        putchar(c);
    }
}

因此,它看起来像是编码问题。运行时,命令提示符打开,标题中带有“ C:\ Users \ username \ Desktop \ filename.exe”,我的用户名包含丹麦字符“å”,并用“ by”代替。命令提示符使用CP 850字符集。

(顺便说一句,我不是在检查字符是否等于EOF,因为这会产生奇怪的结果。按Enter键会打印预期的盒子数,再加上\n的盒子数,但是不会)结束程序。)

4 个答案:

答案 0 :(得分:7)

您在这里看到运算符优先级的问题。如您在this chart上所见,=的优先级低于!=

这意味着getchar() != '\n'首先被评估。

对于编译器,您的代码如下所示:

#include <stdio.h>

int main() {
    char c;

    while (c = (getchar() != '\n')) { 
        putchar(c);
    }
}

由于'c'的值不正确(表达式的真/假评估),所以输出不正确,但是程序给出了您所看到的行为。

#include <stdio.h>

int main() {
    char c;

    while ((c = getchar()) != '\n') { //<----notice brackets around c=getchar 
        putchar(c);
    }
}

给出您期望的输出。这说明了一个事实,即为了安全起见,应始终在这些表达式两边加上括号。

答案 1 :(得分:3)

这条线不好。

while (c = getchar() != '\n') 

应该是:

while ((c = getchar()) != '\n') 

答案 2 :(得分:2)

问题范围内已经有一些正确答案,但是您需要解决两个更广泛的问题。

首先getchar()返回一个int,并且重要的是定义一个将返回值作为int的变量,以便区分错误和文件末尾与有效{{ 1}} s。

第二,如果您在程序遇到char之前收到文件结尾或stdin上有错误,则代码将永远循环。这就是笔记本电脑上的手册页上关于\n

的内容
  

如果成功,这些例程将从流中返回下一个请求的对象。字符值以无符号字符形式返回,并转换为整数。如果流位于文件末尾或发生读取错误,则例程将返回EOF。

因此,一旦getchar()返回getchar(),它将一直返回EOF。您需要在循环条件下解决此问题:

EOF

答案 3 :(得分:0)

编辑:由于在作业周围缺少括号,您得到了这些框,请查看this问题以供您为什么为什么要加上括号用作真值 ...

的作业

此外,此程序还存在其他问题,请考虑以下示例:-

例如:

  

您实际想要的是:-

     
    

ABCD
     <换行>

  
     

您实际输入的内容:-

     
    

ABCD

  

由于该程序未在代码中的任何地方找到'\n',因此导致无法定义的行为,因为它无法找到它...

当您的输入不包含'\n'时,有两种可能的解决方案:-

  • 使用EOF(由很多建议,因为这是接受每个输入的最佳解决方案...)

    int main() {
        char c;
        while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
                                           an assignment in a condition... */
            putchar(c);
    }
    
  • 在输入中添加换行符:-

    int main() {
        char c;
        // Use fputc to modify input...
        fputc('\n', stdin);
        while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
                                           an assignment in a condition... */
            putchar(c);
    }
    

    但是,请注意!!此方法将在获取换行的第一个迭代时停止 ,因此,如果您在'\n'之外有其他内容,将不会被打印...