C语言标准输入流stdin与流相关的各个函数之间的关联研究

    在学习到C语言的缓冲区的时候,本来是一切顺利的,结果看到了说是stdin、stdout、stderr三个标准流是一个文件指针,可以当作像普通文件指针fp那样进行函数的操作,这让我想起了有关文件指针相关的fgetc、fputc、fgets、fputs、fscanf、fprintf以及puts和gets这一系列的函数,还有最基础的scanf和getchar函数,给我彻底搞懵圈了,然后我就针对其中的scanf、getchar、fgets、fputs、puts做了一些研究,下面是代码:

#include <stdio.h>
#include <stdlib.h>
void main()
{
	int i;
	int ch_int;
	char ch_char, ch_string[50];
	printf("========测试scanf与stdin关系========\n");
	printf("开始:stdin位置标识符:%d\n", ftell(stdin));
	printf("输入三个整数(每个整数之间用空格隔开):");
	while (scanf("%d", &ch_int) == 1)
	{
		printf("ch_int = %d\n", ch_int);
		printf("中间:stdin位置标识符:%d\n", ftell(stdin));
		if ((ch_int = getchar()) == '\n')
		{
			// 为了实验的严谨性,使用getchar提取到的换行符'\n'在达到跳出循环的目的之前,要先重新归还给stdin里
			printf("返回回车键:%d(ascii = 10为换行符'\\n')\n", ungetc(ch_int, stdin));
			printf("结束:stdin位置标识符:%d\n", ftell(stdin));
			break;
		}
	}
	// 所以如果要连续使用多次scanf函数接收int、char型数据的时候,相隔两次中要添加一个getchar()函数用来接收stdin中剩余的换行符'\n'
	printf("检测本次getchar会不会接收到键盘输入的换行符:%d(ascii = 10为换行符'\\n')\n", getchar());

	printf("\n重置之前:stdin位置标识符:%d\n", ftell(stdin));
	printf("将stdin的位置标识符重置...\n");
	rewind(stdin);
	// 由此可知,一经scanf等函数从stdin中读出完数据的时候,其数据也被一并从中移除
	printf("重置之后:stdin位置标识符:%d\n", ftell(stdin));

	printf("检测经过scanf函数扫描之后stdin中是否保存有之前的数据...\n");
	// 本行的getchar()要另外从键盘中读取数据
	printf("getchar() = %d(ascii = 10为换行符'\\n')\n", getchar());
	printf("检测之后:stdin位置标识符:%d\n", ftell(stdin));

	printf("\n输入三个字符(每个字符之间用空格隔开):");
	// 通过实践得知,当调用新的scanf函数,stdin的位置标识符会被重置成0
	while (scanf("%c", &ch_char) == 1)
	{
		printf("ch_char = %c\n", ch_char);
		printf("中间:stdin位置标识符:%d\n", ftell(stdin));
		if ((ch_char = getchar()) == '\n')
		{
			printf("返回回车键:%d(ascii = 10为换行符'\\n')\n", ungetc(ch_char, stdin));
			printf("结束:stdin位置标识符:%d\n", ftell(stdin));
			break;
		}
	}
	printf("检测本次getchar会不会接收到键盘输入的换行符:%d(ascii = 10为换行符'\\n')\n", getchar());

	printf("\n输入三个字符串(每个字符串之间用空格隔开):");
	while (scanf("%s", ch_string) == 1)
	{
		printf("ch_string = %s\n", ch_string);
		printf("中间:stdin位置标识符:%d\n", ftell(stdin));
		if ((ch_char = getchar()) == '\n')
		{
			printf("返回回车键:%d(ascii = 10为换行符'\\n')\n", ungetc(ch_char, stdin));
			printf("结束:stdin位置标识符:%d\n", ftell(stdin));
			break;
		}
	}
	printf("检测本次getchar会不会接收到键盘输入的换行符:%d(ascii = 10为换行符'\\n')\n", getchar());

	printf("\n========测试fputs、fgets、gets与stdin关系========\n");
	rewind(stdin);
	printf("开始:stdin位置标识符:%d\n", ftell(stdin));

	printf("将字符串'abcdefg\\n'利用fputs函数写入stdin中...");
	// 通过结果得知无法使用fputs函数对stdin人为写入数据
	if (fputs("abcdefg\n", stdin) >= 0)
		printf("执行成功!\n");
	else
		printf("执行失败!\n");
	printf("执行fputs之后:stdin位置标识符:%d\n", ftell(stdin));

	// 这里只能是利用gets函数另外从键盘中读取新的字符串
	printf("尝试利用gets函数能否提取出刚刚写入的字符串...:");
	printf("该字符串为%s\n", gets(ch_string));
	printf("执行gets之后:stdin位置标识符:%d\n", ftell(stdin));

	// stdin可以利用fgets函数从键盘中读取一个字符串
	printf("利用fgets函数读取stdin...:");
	if (fgets(ch_string, 50, stdin) != NULL)
		printf("执行成功!,字符串为:%s\n", ch_string);
	else
		perror("执行失败!原因是");
	printf("执行fgets之后:stdin位置标识符:%d\n", ftell(stdin));
}

以下是执行结果:

========测试scanf与stdin关系========
开始:stdin位置标识符:0
输入三个整数(每个整数之间用空格隔开):11 22 33
ch_int = 11
中间:stdin位置标识符:2
ch_int = 22
中间:stdin位置标识符:5
ch_int = 33
中间:stdin位置标识符:8
返回回车键:10(ascii = 10为换行符'\n')
结束:stdin位置标识符:8
检测本次getchar会不会接收到键盘输入的换行符:10(ascii = 10为换行符'\n')

重置之前:stdin位置标识符:10
将stdin的位置标识符重置...
重置之后:stdin位置标识符:0
检测经过scanf函数扫描之后stdin中是否保存有之前的数据... 

getchar() = 10(ascii = 10为换行符'\n')
检测之后:stdin位置标识符:2

输入三个字符(每个字符之间用空格隔开):a b c
ch_char = a
中间:stdin位置标识符:1
ch_char = b
中间:stdin位置标识符:3
ch_char = c
中间:stdin位置标识符:5
返回回车键:10(ascii = 10为换行符'\n')
结束:stdin位置标识符:5
检测本次getchar会不会接收到键盘输入的换行符:10(ascii = 10为换行符'\n')

输入三个字符串(每个字符串之间用空格隔开):aaa bbb ccc
ch_string = aaa
中间:stdin位置标识符:3
ch_string = bbb
中间:stdin位置标识符:7
ch_string = ccc
中间:stdin位置标识符:11
返回回车键:10(ascii = 10为换行符'\n')
结束:stdin位置标识符:11
检测本次getchar会不会接收到键盘输入的换行符:10(ascii = 10为换行符'\n')

========测试fputs、fgets、gets与stdin关系========
开始:stdin位置标识符:0
将字符串'abcdefg\n'利用fputs函数写入stdin中...执行失败!
执行fputs之后:stdin位置标识符:0
尝试利用gets函数能否提取出刚刚写入的字符串...:lalala
该字符串为lalala
执行gets之后:stdin位置标识符:8
利用fgets函数读取stdin...:1234567
执行成功!,字符串为:1234567

执行fgets之后:stdin位置标识符:9

望大佬斧正! 

猜你喜欢

转载自blog.csdn.net/weixin_48896613/article/details/119873865