如果要实现指定字符串在标准输出流(一般为显示器)上闪烁,可以定义如下函数:

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语言 详解如何编写闪烁显示字符串的函数相关推荐

  1. c语言多组数据判断回文字符串,详解判断回文字符串跟回文数算法的C语言代码...

    详解判断回文字符串和回文数算法的C语言代码! 一.判断一个字符串是否为回文字符串 #include #include #include //包含strlen #define YES 1 #define ...

  2. 如何用c语言编写stm32的程序吗,STM32入门C语言详解

    <STM32入门C语言详解>由会员分享,可在线阅读,更多相关<STM32入门C语言详解(6页珍藏版)>请在人人文库网上搜索. 1.最新 料推荐阅读 flash : 芯片内部存储 ...

  3. 邻接矩阵用c语言,邻接矩阵无向图(一)之 C语言详解

    本章介绍邻接矩阵无向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实 ...

  4. c++指针详解_c语言详解sizeof

    一.sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等. 它并不是函数. sizeof操作符以字节形式给出了其操作数的存储大小. 操作数可以是一个表达式或括在括 ...

  5. 排座系统c语言,2008noip排座位C语言详解.doc

    2008noip排座位C语言详解 2008noip排座位C语言详解 2.排座椅 (seat.pas/c/cpp)D对同学上课时会交头接耳.同学们在教室中坐成了M行N列,坐在第i行第j列 的同学的位置是 ...

  6. 【C语言详解】——文件操作(建议收藏)

    前言:本期我们就进入C语言的最后一部分--文件操作,说起文件,广大学子可以说苦其久已,但实际上文件这部分要掌握的内容并不多,熟知其原理即可.因为在以后的实际应用中几乎不会使用到C语言的文件,一般都是使 ...

  7. JAVA算法:回文字符串相关问题详解(回文字符串总结)

    JAVA算法:回文字符串相关问题详解(回文字符串总结) Q1. 编写一个工具方法判断给定的字符串是否为回文字符串 例如:给定一个字符串"aabbaa",判断该字符串是否为回文字符串 ...

  8. smali语言详解之static静态代码块的声明与静态变量初始化赋值位置

    smali语言详解之static静态代码块的声明与静态变量初始化赋值位置 一.smali语言的静态代码块声明格式 .method static constructor <clinit>() ...

  9. smali语言详解之一般/构造方法(函数)的声明与返回值关键字

    smali语言详解之一般/构造方法(函数)的声明与返回值关键字 一. smali语言的方法声明格式 .method与.end method成对出现,类似于java中的花括号 1.1.非静态的一般方法 ...

最新文章

  1. MooTools教程(1):认识MooTools
  2. 解决安装完ubuntu登陆无root账户问题
  3. Linux Qt使用POSIX多线程条件变量、互斥锁(量)
  4. Codeforces Round #579 (Div. 3) F1. Complete the Projects (easy version) 排序 + 贪心
  5. 没有桌面体验功能就不能进行图片打印
  6. hdu 2883 kebab 网络流
  7. MVC IIS创建过程问题收录
  8. paip.验证码识别---初始化
  9. 镁光固态硬盘用什么软件测试寿命,最简单的方法:如何查看SSD可以使用多长时间?固态硬盘寿命测试方法[详细]...
  10. Windows系统语言切换问题
  11. 教你怎么从Windows10彻底删除Flash
  12. 华为性格面试的技巧方法
  13. 【数据分析】基于RFM模型的线上零售中的客户细分(二):RFM模型实战
  14. 梯度弥散与梯度爆炸及其解决方法
  15. 一个坑firewall-cmd: error: unrecognized arguments
  16. 2022年数据中心产业发展将呈现三大新趋势
  17. 安装软件出现nsis error对话框的解决方法
  18. 乐忧商城项目总结-4
  19. 软件综合实践专题--结对编程
  20. 《快速念咒——MySQL自学入门指南》:第2章——从表中获取更多数据(前言)

热门文章

  1. 项目商业模式的设计与思考
  2. 嵌入式工程师学习第一天
  3. 平板win10 android哪个耗电,win10开启平板模式省电吗?win10平板模式省电方法
  4. Linux主机定期打补丁修复漏洞
  5. mallet java_Mallet:自然语言处理工具包
  6. Exchange Server 2016 RTM快速部署指南
  7. 2017年8月1日,星期二
  8. Python 爬取 QQ 空间说说和相册
  9. 如何在中国制造网(made-in-china)上做生意
  10. 库客音乐2021年财报:拥抱素质教育新蓝海