C 如何模拟“a”的类似终端的行为;聊天机器人“;节目?

C 如何模拟“a”的类似终端的行为;聊天机器人“;节目?,c,C,我是C语言的初学者,这也是我关于StackOverflow的第一篇文章 我目前正在尝试在C上构建一个类似“机器人”的行为,用标准文本进行读写。我希望它的行为类似于终端。在从输入流读取某些值时,我遇到了一些问题:(在这两种情况下,预期要扫描的输入都是int) 第1个问题-用户名写入流的次数与我输入非整数字符的次数相同(终端如下) 第二个问题-当我在未键入任何内容的情况下按enter键时,不会显示用户名(以下终端): 代码类似于此行为: #include <stdio.h> int ma

我是C语言的初学者,这也是我关于StackOverflow的第一篇文章

我目前正在尝试在C上构建一个类似“机器人”的行为,用标准文本进行读写。我希望它的行为类似于终端。在从输入流读取某些值时,我遇到了一些问题:(在这两种情况下,预期要扫描的输入都是int

第1个问题-用户名写入流的次数与我输入非整数字符的次数相同(终端如下)

第二个问题-当我在未键入任何内容的情况下按enter键时,不会显示用户名(以下终端):

代码类似于此行为:

#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