【C 语言笔记】解决控制台闪烁/鬼畜/光标乱跑问题

问题

如果你要在控制台里“画”一些频繁更新的东西,比如做个小游戏,常见的思路是:

while(1)
{
	//先清空
	system("clear");
	//再画
	printf(".....");
}

然后控制台的就闪个不停,很瞎眼。

解决 0

降低刷新频率,能明显缓解问题。
也就是

#include <windows.h> //需要这个文件头
while(1)
{
	//先清空
	system("clear");
	//再画
	printf(".....");
	//延时
	Sleep(100);
}

解决 1

不要清空整个屏幕,只更新必要的部分。
利用 coino.hgotoxy 函数,可以移动光标的位置,这样就可以做到只修改某行某列的字符了。
(如果用 visual studio,可以参考 https://zhuanlan.zhihu.com/p/460165739)

例如,地图 + 玩家,地图一般都是静态的,所以只用在开头的时候画一遍,后面人物移动就只更新人物即可。

画地图();
while(1)
{
	if(玩家移动())
	{
		gotoxy(玩家新x, 玩家新y);
		putchar('我');
		//玩家原来的位置要恢复
		gotoxy(玩家旧x, 玩家旧y);
		putchar(地图上这一格对应的字符);
	}
}

解决 2

直接覆写或输出空格来实现“清屏”,尽量避免使用 system("cls")
或者说是“部分清屏”。

改变思想:在计算机里,不需要的东西没必要一定丢掉清空,可以直接用新的覆盖上去。

解决 3

取消自动刷新缓冲区,然后手动刷新缓冲区。
这个可以解决光标鬼畜到处跑的问题,尤其是你的 gotoxy 用的比较多的时候这个问题比较明显。

while(1)
{
	setvbuf(stdout, NULL, _IOFBF, 4096); // 1:修改刷新模式为手动刷新
	//然后画你要画的东西
	printf("...");
	fflush(stdout); // 2:清空并输出缓冲区的内容
	setvbuf(stdout, NULL, _IOLBF, 4096); // 3:刷新模式改回去
}

相当于原来是一行一行显示,改了之后就是一整块一整块显示。
原来每显示一行光标移一下,就造成了乱跑的问题。

(当然,你也可以选择直接隐藏光标)

源代码

int main()
{
	while (1)
	{
		system("cls");
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
	}
	return 0;
}

1


降低刷新率:


int main()
{
	while (1)
	{
		system("cls");
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
		printf("%d\n", rand());
		Sleep(100);
	}
	return 0;
}

2


改用 gotoxy 和直接覆盖:
(注意!延时没了)

int main()
{
	while (1)
	{
		gotoxy(0, 0);
		printf("%d", rand());
		printf("         \n"); //因为数字长度不一样,所以用空格覆盖掉上次比这次长的部分
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
	}
	return 0;
}

3


手动刷新缓冲区:

int main()
{
	while (1)
	{
		setvbuf(stdout, NULL, _IOFBF, 4096);
		gotoxy(0, 0);
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		printf("%d", rand());
		printf("         \n");
		fflush(stdout);
		setvbuf(stdout, NULL, _IOLBF, 4096);
	}
	return 0;
}

4

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值