C语言 详解如何编写闪烁显示字符串的函数
如果要实现指定字符串在标准输出流(一般为显示器)上闪烁,可以定义如下函数:
void bput(const char*s,int appe,int disa,int repe)
字符串s出现appe秒后,消失disa秒,重复以上操作repe次返回到调用方。
一、具体代码
#include<time.h>
#include<stdio.h>
#include<string.h>void bput(char*s,int appe,int disa,int repe)
{int char_len = strlen(s);for(int i = 0;i < repe;i++){printf("\r%s",s);clock_t t1 = clock();clock_t t2 = 0;while(1000*(t2-t1)/CLOCKS_PER_SEC<appe){t2 = clock();}printf("\r%*s",char_len,"");clock_t t3 = clock();clock_t t4 = 0;while(1000*(t4-t3)/CLOCKS_PER_SEC<disa){t4 = clock();}}
}int main()
{int appe = 0;int disa = 0;int repe = 0; char s[20] = "";printf("输入一个长度20以内的字符串:>");gets(s);printf("输入显示的毫秒数,消失的毫秒数,反复执行的次数(以空格隔开)");scanf("%d %d %d",&appe,&disa,&repe);bput(s,appe,disa,repe);return 0;
}
让我们来具体解读一下bput函数的内容。
二、strlen函数:查询字符串的长度
strlen |
头文件 #include<string.h> |
格式 size_t strlen(const char *s) |
功能 计算s所指定的字符串长度(不包含空字符的字符数) |
返回值 返回值size_t表示末尾的空字符前面的字符的个数 |
函数接受的参数为字符指针或字符数组,不要随意改动字符串,改动后地址将会发生变化,所以用const修饰。
#include<stdio.h>
#include<string.h>
int main()
{const char*a = "ABCDEF";const char b[] = "ABCDEF";int a_len = strlen(a);int b_len = strlen(b);printf("%d %d",a_len,b_len);//运行结果为6 6return 0;
}
三、clock函数
clock |
头文件 #include<time.h> |
格式 clock_t clock() |
功能 求处理器调用某个进程所花费的时间 |
返回值 从定义与程序启动相关的编程环境的时间点起,用处理系统的最佳逼近返回程序占用处理 器的时间。默认返回为clock_t型时钟周期的总数,为了以秒为计量单位,必须用本函数除 以CLOCKS_PER_SEC宏的值。如果无法获取处理器调用该进程所花费的时间,或无法显 示数值,就返回值(clock_t)-1。(加粗的字体后面会解释) |
这里可以具体化为下图
得到时钟数后除以CLOCKS_PER_SEC宏的值(该编译环境下为1000)即可得到该次调用clock函数时,程序历经的时间(秒)。
clock_t型:该编译环境下将clock_t等同于unsigned型。clock_t等同于哪种类型(unsigned、unsigned long……)由编译环境决定。
CLOCKS_PER_SEC宏:由头文件<time.h>定义。直译为“每秒的时钟数”,如果时钟的精确度为0.001秒,那么一秒内就有1000个时钟,这个宏的值就定义为1000。不同的硬件和OS会导致时钟的精确度也不同,所以clock_t型表示数值的单位也取决于编程环境。
(clock_t)-1:指将-1强制转换成clock_t型,而不是指clock_t的值减1。
我们可以使用clock函数求两个时间点的差值以计算两次clock函数的时间点之间的时钟差:
#include<stdio.h>
#include<time.h>
int main()
{clock_t t1 = clock();//计时起点 clock_t t2 = 0;/*一段程序 */t2 = clock();//计时终点 double t = (t2 - t1)/CLOCKS_PER_SEC;//时钟差除以每秒时钟数,计算时间差(秒) printf("运行这段程序用了%lf秒",t);return 0;
}
如果我们先定义t1,再在一个循环内不断更新t2的值,并将(t2-t1)/CLOCKS_PER_SEC<x(x为指定秒数)作为循环的判断条件,即可达到使程序暂停x秒后再运行(在此时间段内运行循环)的效果:
#include<stdio.h>
#include<time.h>
int main()
{clock_t t1 = clock();//计时起点 clock_t t2 = 0;int x = 0;scanf("%d",&x);while((t2-t1)/CLOCKS_PER_SEC<x){t2 = clock();//更新t2的时钟数}return 0;
}
综上易知,如果将(t2-t1)/CLOCKS_PER_SEC的分母乘1000,就可以得到程序运行的毫秒数。
#include<stdio.h>
#include<time.h>
int main()
{clock_t t1 = clock();clock_t t2 = 0;int x = 0;//此时x为毫秒数scanf("%d",&x);while(1000*(t2-t1)/CLOCKS_PER_SEC<x)//分母乘1000,与毫秒作比较{t2 = clock();}return 0;
}
当然,使用clock函数来使程序暂停运行的效果,Sleep函数也可以达到:
#include<stdio.h>
#include<windows.h>//头文件windows.h
int main()
{int x = 0;scanf("%d",&x);Sleep(x);//参数x为毫秒数return 0;
}
#include<stdio.h>
#include<windows.h>//头文件为windows.h
int main()
{int a = 300;for(int i = 0;i<10;i++){printf("\rABC");Sleep(a);//参数可为变量printf("\r%*s",3,"");Sleep(300);//参数可为常量}return 0;
}
Sleep(int)函数的头文件为windows.h,参数可以为变量或常量。
使用如上的代码也可以实现字符串的闪烁显示,下面介绍\r和%*s使标准输出流上的字符串"ABC"和三个""交替覆盖显示的原理。
四、\r 、%*.*
回车符\r:输出回车符\r后,显示光标就会移动到本行开头。本行已显示字符串b的情况下,在\r后显示的内容a都将覆盖本行已有的内容b。如果a的长度大于b,那么将完全覆盖b的内容;如果a的长度小于b,那么a只从左往右数覆盖等于a长度的内容,其它内容不变。
#include<stdio.h>
#include<windows.h>
int main()
{char*b = "最开始bbbbb";printf("%s",b);Sleep(1000);char*a = "修改后aaaaa";printf("\r%s",a);
}
输出内容:
****一秒后
如果修改后内容的长度比修改前的内容短,
#include<stdio.h>
#include<windows.h>
int main()
{char*b = "最开始bbbbb";printf("%s",b);Sleep(1000);char*a = "修改后aa";printf("\r%s",a);
}
就会出现以下输出内容:
如果在循环中反复在本行开头显示两个字符串,让空白字符串和要显示的字符串交替覆盖,两个字符串等长或是空白字符串大于要显示的字符串时,即可达到让字符串闪烁显示的效果:
#include<stdio.h>
#include<windows.h>
int main()
{char*b = "最开始bbbbb";char*a = " ";for(int i = 0;i<10;i++)//闪烁10次 {printf("\r%s",b);Sleep(300);printf("\r%s",a);Sleep(300);}
}
在自定义字符串内容的情况下,提前准备一个等长的空白字符串显然不现实,那么我们可以用printf函数中的%*.*来控制输出的空白数量。然而这些"*"都可以替换为数字来实现printf函数中输出内容外指定"*"的值而达到的效果。
先讨论句点(.)左边的"*"。左边的"*"可以控制输出内容的最小输出宽度,如果输出内容达不到最小输出宽度,则在左侧用空格补全至最小宽度(在左侧指定了"-"的情况下,在右侧补全空格至最小宽度)。这个"*"也可以替换为数字来实现相同效果:
include<stdio.h>
int main()
{int a = 20;printf("%*d",4,a);//输出结果为: 20(共有4个字节的长度) printf("%4d",a);//输出结果与在内容外控制"*"的值的效果相同
}
如果将printf函数要输出的内容改变成一个空字符串,并使用变量改变"*"的数值,以此输出内容的宽度,就可以输出自己指定长度的空白:
#include<stdio.h>
int main()
{int len= 0;scanf("%d",&len);printf("\r%*s",len,"");//""代表输出空字符串
}
这样就可以得到想要长度的空白了。
句点(.)右侧的"*"(同时也可以是数字)在不同情况下的作用不同,总体概括为精度:
- d、i、o、u、x、X(整形)情况下,代表最小输出位数。
- e、E、f(浮点型)情况下,代表小数点后的输出位数。
- g、G(指数型)情况下,代表有效位数。
- s(字符串)情况下,代表从字符串中能输出的最大字符数。
五、总结
有了这些基础知识之后,我们再来看开头的函数就轻松得多了:
#include<time.h>
#include<stdio.h>
#include<string.h>void bput(char*s,int appe,int disa,int repe)//appe和disa为毫秒数,所以后边要*1000
{int char_len = strlen(s);//测得字符串数组s的长度for(int i = 0;i < repe;i++)//重复repe次循环{printf("\r%s",s);//将光标移动到开头,并输出字符内容clock_t t1 = clock();//初始化并开始记录此时的时钟数t1clock_t t2 = 0;//初始化t2while(1000*(t2-t1)/CLOCKS_PER_SEC<appe)//appe为毫秒数,所以前面乘1000{ //显示appe毫秒t2 = clock();//随时更新t2的时钟数}printf("\r%*s",char_len,"");//利用句点前的*输出和s等长的空白字符串(宽度相等的空字符串)clock_t t3 = clock();//同t1,记录此刻时钟数clock_t t4 = 0;while(1000*(t4-t3)/CLOCKS_PER_SEC<disa)//消失disa毫秒{t4 = clock();}}
}int main()
{int appe = 0;int disa = 0;int repe = 0; char s[20] = "";printf("输入一个长度20以内的字符串:>");gets(s);printf("输入显示的毫秒数,消失的毫秒数,反复执行的次数(以空格隔开)");scanf("%d %d %d",&appe,&disa,&repe);bput(s,appe,disa,repe);return 0;
}
当然这里的两次停顿也可以在引入windows.h头文件后使用Sleep函数代替。
//本人是刚接触c语言不久的小白,如有错误和不足还请指正:)
C语言 详解如何编写闪烁显示字符串的函数相关推荐
- c语言多组数据判断回文字符串,详解判断回文字符串跟回文数算法的C语言代码...
详解判断回文字符串和回文数算法的C语言代码! 一.判断一个字符串是否为回文字符串 #include #include #include //包含strlen #define YES 1 #define ...
- 如何用c语言编写stm32的程序吗,STM32入门C语言详解
<STM32入门C语言详解>由会员分享,可在线阅读,更多相关<STM32入门C语言详解(6页珍藏版)>请在人人文库网上搜索. 1.最新 料推荐阅读 flash : 芯片内部存储 ...
- 邻接矩阵用c语言,邻接矩阵无向图(一)之 C语言详解
本章介绍邻接矩阵无向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实 ...
- c++指针详解_c语言详解sizeof
一.sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等. 它并不是函数. sizeof操作符以字节形式给出了其操作数的存储大小. 操作数可以是一个表达式或括在括 ...
- 排座系统c语言,2008noip排座位C语言详解.doc
2008noip排座位C语言详解 2008noip排座位C语言详解 2.排座椅 (seat.pas/c/cpp)D对同学上课时会交头接耳.同学们在教室中坐成了M行N列,坐在第i行第j列 的同学的位置是 ...
- 【C语言详解】——文件操作(建议收藏)
前言:本期我们就进入C语言的最后一部分--文件操作,说起文件,广大学子可以说苦其久已,但实际上文件这部分要掌握的内容并不多,熟知其原理即可.因为在以后的实际应用中几乎不会使用到C语言的文件,一般都是使 ...
- JAVA算法:回文字符串相关问题详解(回文字符串总结)
JAVA算法:回文字符串相关问题详解(回文字符串总结) Q1. 编写一个工具方法判断给定的字符串是否为回文字符串 例如:给定一个字符串"aabbaa",判断该字符串是否为回文字符串 ...
- smali语言详解之static静态代码块的声明与静态变量初始化赋值位置
smali语言详解之static静态代码块的声明与静态变量初始化赋值位置 一.smali语言的静态代码块声明格式 .method static constructor <clinit>() ...
- smali语言详解之一般/构造方法(函数)的声明与返回值关键字
smali语言详解之一般/构造方法(函数)的声明与返回值关键字 一. smali语言的方法声明格式 .method与.end method成对出现,类似于java中的花括号 1.1.非静态的一般方法 ...
最新文章
- MooTools教程(1):认识MooTools
- 解决安装完ubuntu登陆无root账户问题
- Linux Qt使用POSIX多线程条件变量、互斥锁(量)
- Codeforces Round #579 (Div. 3) F1. Complete the Projects (easy version) 排序 + 贪心
- 没有桌面体验功能就不能进行图片打印
- hdu 2883 kebab 网络流
- MVC IIS创建过程问题收录
- paip.验证码识别---初始化
- 镁光固态硬盘用什么软件测试寿命,最简单的方法:如何查看SSD可以使用多长时间?固态硬盘寿命测试方法[详细]...
- Windows系统语言切换问题
- 教你怎么从Windows10彻底删除Flash
- 华为性格面试的技巧方法
- 【数据分析】基于RFM模型的线上零售中的客户细分(二):RFM模型实战
- 梯度弥散与梯度爆炸及其解决方法
- 一个坑firewall-cmd: error: unrecognized arguments
- 2022年数据中心产业发展将呈现三大新趋势
- 安装软件出现nsis error对话框的解决方法
- 乐忧商城项目总结-4
- 软件综合实践专题--结对编程
- 《快速念咒——MySQL自学入门指南》:第2章——从表中获取更多数据(前言)