在程序中同时使用puts()、gets()、getchar()、putchar()函数
我对在代码中同时使用在程序中同时使用puts()、gets()、getchar()、putchar()函数,c,getchar,gets,puts,putchar,C,Getchar,Gets,Puts,Putchar,我对在代码中同时使用put()、get()、putchar()和getchar()感到困惑 当我运行以下代码时,它正在执行所有步骤: 获取输入,打印输出,再次获取输入,打印输出 #include <stdio.h> int main() { char ch[34]; gets(ch); puts(ch); char g; g = getchar(); putchar(g); } 但是,当我使用此代码时: 它只做了两个步骤: 获取输
put()
、get()
、putchar()
和getchar()
感到困惑
当我运行以下代码时,它正在执行所有步骤:
获取输入,打印输出,再次获取输入,打印输出
#include <stdio.h>
int main() {
char ch[34];
gets(ch);
puts(ch);
char g;
g = getchar();
putchar(g);
}
但是,当我使用此代码时:
它只做了两个步骤:
获取输入,打印输入,然后是一行空间。我不明白它为什么会这样
代码:
在我不建议使用的语句
putchar()
和gets()
的行之间,在EOF或换行符出现之前丢弃输入流可以解决问题:
.
.
int c;
while ((c = getchar()) != EOF && c != '\n')
;
.
.
我建议使用更安全的方法,例如:
char str[1024];
if (fgets(str, sizeof str, stdin) == NULL) {
// Some problem, handle the error...
}
// or, Input is okay...
代码中存在一些问题,输入机制比您推断的更复杂:
- 不应使用
读取输入:此函数无法安全使用,因为它不接收有关目标数组大小的信息,因此任何足够长的输入行都将导致缓冲区溢出。它已从C标准中删除。您应该改为使用gets()
,并处理缓冲区末尾的换行符fgets()
应具有类型g
,以适应int
返回的所有值,即getc()
无符号字符类型的所有值(在大多数当前系统中
到0
)和特殊负值255
(通常为-1)EOF
#include <stdio.h>
int main() {
char ch[34];
if (fgets(ch, sizeof ch, stdin))
fputs(ch, stdout);
int g = getchar();
if (g != EOF)
putchar(g);
return 0;
}
关于控制台响应程序输入请求的行为,它是实现定义的,但通常涉及两层缓冲:
流包实现了一种缓冲方案,其中数据以块的形式从系统中读取或写入。可以使用文件
控制此缓冲。3种设置可用:无缓冲(这是setvbuf()
的默认设置)、行缓冲(通常是stderr
和stdin
在连接到字符设备时的默认设置)以及使用可自定义块大小(常用大小为512和4096)完全缓冲stdout
- 当您调用
或更一般的getchar()
时,如果流的缓冲区中有一个字节可用,则返回该字节并递增流的位置,否则会向系统请求填充缓冲区getc(stream)
- 如果流附加到文件,则填充缓冲区将执行
系统调用或等效调用,除非在文件末尾或读取错误时成功读取
- 如果流连接到字符设备,如终端或虚拟tty(如图形显示器上的终端窗口),则会涉及另一层缓冲,其中设备驱动程序从输入设备读取输入,并以特殊方式(如退格)处理一些键以擦除前一个字符,光标移动键在输入行内移动,Ctrl-D(unix)或Ctrl-Z(windows)表示文件结束。这一层缓冲可以通过
系统调用或其他特定于系统的API进行控制。交互式应用程序(如文本编辑器)通常禁用此功能,并直接从输入设备检索原始输入tcsetattr()
- 终端处理用户键入的密钥以形成输入行,当用户输入时发送回C流API(被翻译为系统特定的行尾序列),流函数执行另一组转换(即:在传统系统上将
/CR
转换为LF
)字节行存储在流缓冲区中。当'\n'
最终有机会返回第一个可用字节时,用户已经键入并输入了整行,并且在流或设备缓冲区中挂起getc()
在这两个程序中,
getchar()
不会返回从stdin
读取的下一个字节,直到从终端读取完整的行并存储在流缓冲区中。在第一个程序中,该行的其余部分在程序退出时被忽略,但在第二个程序中,该行的其余部分可供后续的get()
读取。如果键入J并输入,则读取的行为J\n
,getchar()
返回'J'
,保留换行符[在输入流中结束,然后gets())
将读取换行符并返回一个空行。好吧,这里有一个问题。您在第二个示例代码中使用的函数不是stdio包的一部分
你调用getch()
,它不是一个stdio函数。它是ncurses库的一部分,如果你在编译时没有指定要使用它,那么你就不能得到一个可执行的程序。所以这让我觉得你说的不是所有的事实
只需使用程序的函数getch()
,就可以得到完整的行
Priyanka
输出,程序终止。我猜您使用了getch()
来停止输出,直到您按下一个字符为止。但是由于curses库要求您在调用任何其他curses库函数之前调用initscr()
,因此它没有正确初始化,您得到的输出可能会因此出错
我不会重复其他人已经告诉您的关于使用get()的内容
,它仍然在标准库中,并且知道您在做什么,您仍然可以在适当控制的环境中使用它。尽管如此,其他人给您的建议在这里并不适用,因为您没有溢出您使用的短缓冲区(只有34个字符,太短,太容易挂起或崩溃程序)
来自stdio的函数使用缓冲区,而
char str[1024];
if (fgets(str, sizeof str, stdin) == NULL) {
// Some problem, handle the error...
}
// or, Input is okay...
#include <stdio.h>
int main() {
char ch[34];
if (fgets(ch, sizeof ch, stdin))
fputs(ch, stdout);
int g = getchar();
if (g != EOF)
putchar(g);
return 0;
}
Priyanka
Priyanka
J
J
Priyanka