C 如何模拟“a”的类似终端的行为;聊天机器人“;节目?
我是C语言的初学者,这也是我关于StackOverflow的第一篇文章 我目前正在尝试在C上构建一个类似“机器人”的行为,用标准文本进行读写。我希望它的行为类似于终端。在从输入流读取某些值时,我遇到了一些问题:(在这两种情况下,预期要扫描的输入都是int) 第1个问题-用户名写入流的次数与我输入非整数字符的次数相同(终端如下) 第二个问题-当我在未键入任何内容的情况下按enter键时,不会显示用户名(以下终端): 代码类似于此行为:C 如何模拟“a”的类似终端的行为;聊天机器人“;节目?,c,C,我是C语言的初学者,这也是我关于StackOverflow的第一篇文章 我目前正在尝试在C上构建一个类似“机器人”的行为,用标准文本进行读写。我希望它的行为类似于终端。在从输入流读取某些值时,我遇到了一些问题:(在这两种情况下,预期要扫描的输入都是int) 第1个问题-用户名写入流的次数与我输入非整数字符的次数相同(终端如下) 第二个问题-当我在未键入任何内容的情况下按enter键时,不会显示用户名(以下终端): 代码类似于此行为: #include <stdio.h> int ma
#include <stdio.h>
int main(void) {
int val;
printf("Bot> Enter an int\n");
do {
printf("Me> ");
scanf("%d", &val);
} while(getchar() != '\n');
printf("Bot> OK\n");
return 0;
}
#包括
内部主(空){
int-val;
printf(“Bot>输入int\n”);
做{
printf(“Me>”);
scanf(“%d”和&val);
}而(getchar()!='\n');
printf(“Bot>OK\n”);
返回0;
}
我正在努力使我的程序尽可能强大和友好(我尝试在scanf中使用getchar()来防止程序进入无限循环,但它没有解决上述任何问题。)您有什么建议吗
提前谢谢。用于
scanf
的%d
格式将自动删除前导空格(如换行符)
要使scanf能够判断是否有输入,它必须能够看到第一个非空格字符。如果只是空格(比如换行符),那么scanf
就不会返回
同样相关的是,如果scanf
无法匹配格式字符串,那么它将单独保留输入缓冲区。因此,如果第一个字符是非数字字符,则scanf
将立即返回,下次调用输入函数时,将读取准确的字符
我建议您改为使用阅读整行内容,然后尝试解析该行。如果使用sscanf
解析字符串,请始终检查它是什么。您的代码
int main(void) {
int val;
printf("Bot> Enter an int\n");
do {
printf("Me> "); /* (A) */
scanf("%d", &val); /* (B) */
} while(getchar() != '\n');
return 0;
}
第一个问题是由于标记为(B)的行每次只读取一个非整数字符(并将其ASCII值放入val
)。因此,您输入的字符数是程序在(A)-(B)-(A)之间循环的次数。由于用户没有按enter键,您的程序也没有使用printf(“\n”)打印它代码>,在(A)和(B)之间循环时,所有“Me>”
都打印在同一行上
第二个问题是由于如果不输入任何内容,scanf()
将不会返回。在您提供的这个示例输出上
Me> s
Me> s
Me>
/* (C) */
1
-------
Bot> OK
在第(C)行,scanf()
尚未返回。它仍在读取您的输入,您的代码仍在第(B)行,尚未循环到第(A)行,因此没有输出“Me>”
看起来每次用户点击enter
,您都只想打印一个“Me>”
。如果是这样,请尝试使用getline()
,然后使用sscanf()
处理输入。首先始终检查scanf()
的返回值,查看是否成功。或者更好的是,永远不要使用它。使用“永远不要使用它”,Shawn可能或多或少意味着这篇非常有用的文章中描述的内容:@Yunnosch谢谢你的链接。在继续之前,我会仔细阅读它。确切地说,它是为了了解,而不是为了在所有情况下都遵循它。这是我的荣幸。
int main(void) {
int val;
printf("Bot> Enter an int\n");
do {
printf("Me> "); /* (A) */
scanf("%d", &val); /* (B) */
} while(getchar() != '\n');
return 0;
}
Me> s
Me> s
Me>
/* (C) */
1
-------
Bot> OK