getchar/putchar returns 打印输入字符时带问号的框
getchar/putchar returns boxes with question marks when printing inputted characters
在 Windows10(丹麦语)的 Codeblocks 中使用来自 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);
}
}
看来是编码问题。当 运行 时,命令提示符在 header 中打开并显示 "C:\Users\username\Desktop\filename.exe",我的用户名包含丹麦语字符“å”,该字符被“Õ”取代。命令提示符使用 CP 850 字符集。
(顺便说一句,我不检查字符是否等于 EOF
,因为这会产生奇怪的结果。按 enter 键打印预期的框数,加上一个 \n
,但是它不会结束程序。)
这条线不好。
while (c = getchar() != '\n')
应该是:
while ((c = getchar()) != '\n')
编辑: 由于作业周围缺少括号,您得到方框,查看 this 问题以了解为什么 应该 在用作 真值 ...
的赋值周围加上括号
此外,这个程序还有其他问题,考虑这个例子:-
例如:
What you actually wanted:-
ABCD
< newline >
您实际输入的内容:-
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'
,好吧它不会被打印出来...
您在这里看到了运算符优先级的问题。正如您在 this chart 上看到的那样,=
的优先级低于 !=
。
这意味着 getchar() != '\n'
首先计算。
对于编译器,您的代码如下所示:
#include <stdio.h>
int main() {
char c;
while (c = (getchar() != '\n')) {
putchar(c);
}
}
由于 'c' 得到的值不正确(表达式的 true/false 求值),因此输出不正确,程序给出了您所看到的行为,但是
#include <stdio.h>
int main() {
char c;
while ((c = getchar()) != '\n') { //<----notice brackets around c=getchar
putchar(c);
}
}
给出了您期望的输出。这说明了这样一个事实,即为了安全起见,您应该始终将这些表达式括起来。
问题范围内已经有一些正确答案,但您还需要解决几个更广泛的问题。
首先 getchar()
return 是一个 int
并且重要的是您将采用 return 值的变量定义为 int
这样您可以区分错误和文件结尾与有效的 char
s。
其次,如果在程序遇到 \n
之前收到文件结尾或 stdin
上有错误,您的代码将永远循环。这就是我笔记本电脑上的手册页关于 getchar()
的内容
If successful, these routines return the next requested object from the stream. Character values are returned as an unsigned char converted to an int. If the stream is at end-of-file or a read error occurs, the routines return EOF.
所以一旦 getchar() returns EOF
它就会一直 return EOF
。您需要在循环条件中解决这个问题:
#include <stdio.h>
int main()
{
int c; // c declared as int
while ((c = getchar()) != EOF && c != '\n'))
{
putchar(c);
}
if (c == EOF)
{
// handle errors and end of file as you see fit
}
}
在 Windows10(丹麦语)的 Codeblocks 中使用来自 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);
}
}
看来是编码问题。当 运行 时,命令提示符在 header 中打开并显示 "C:\Users\username\Desktop\filename.exe",我的用户名包含丹麦语字符“å”,该字符被“Õ”取代。命令提示符使用 CP 850 字符集。
(顺便说一句,我不检查字符是否等于 EOF
,因为这会产生奇怪的结果。按 enter 键打印预期的框数,加上一个 \n
,但是它不会结束程序。)
这条线不好。
while (c = getchar() != '\n')
应该是:
while ((c = getchar()) != '\n')
编辑: 由于作业周围缺少括号,您得到方框,查看 this 问题以了解为什么 应该 在用作 真值 ...
的赋值周围加上括号此外,这个程序还有其他问题,考虑这个例子:-
例如:
What you actually wanted:-
ABCD
< newline >您实际输入的内容:-
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'
,好吧它不会被打印出来...
您在这里看到了运算符优先级的问题。正如您在 this chart 上看到的那样,=
的优先级低于 !=
。
这意味着 getchar() != '\n'
首先计算。
对于编译器,您的代码如下所示:
#include <stdio.h>
int main() {
char c;
while (c = (getchar() != '\n')) {
putchar(c);
}
}
由于 'c' 得到的值不正确(表达式的 true/false 求值),因此输出不正确,程序给出了您所看到的行为,但是
#include <stdio.h>
int main() {
char c;
while ((c = getchar()) != '\n') { //<----notice brackets around c=getchar
putchar(c);
}
}
给出了您期望的输出。这说明了这样一个事实,即为了安全起见,您应该始终将这些表达式括起来。
问题范围内已经有一些正确答案,但您还需要解决几个更广泛的问题。
首先 getchar()
return 是一个 int
并且重要的是您将采用 return 值的变量定义为 int
这样您可以区分错误和文件结尾与有效的 char
s。
其次,如果在程序遇到 \n
之前收到文件结尾或 stdin
上有错误,您的代码将永远循环。这就是我笔记本电脑上的手册页关于 getchar()
If successful, these routines return the next requested object from the stream. Character values are returned as an unsigned char converted to an int. If the stream is at end-of-file or a read error occurs, the routines return EOF.
所以一旦 getchar() returns EOF
它就会一直 return EOF
。您需要在循环条件中解决这个问题:
#include <stdio.h>
int main()
{
int c; // c declared as int
while ((c = getchar()) != EOF && c != '\n'))
{
putchar(c);
}
if (c == EOF)
{
// handle errors and end of file as you see fit
}
}