C++在终端、文件中就地覆盖输出的方法

  • 1、在终端就地覆盖输出字符
  • 2、在文件中就地覆盖输出字符
  • 3、总结

1、在终端就地覆盖输出字符

先上效果图,如图1-1所示:

图1-1

对应的程序如下:

#include <iostream>
#include <unistd.h>int main(int argc, char* argv[])
{// 设置为无缓冲setbuf(stdout, NULL);// 隐藏光标std::cout << "\033[?25l";for (int i = 1; i <= 10; i++){std::cout << i << "\r";sleep(1);}// 输出换行并恢复光标(光标不见了可以在终端执行 echo -e "\033[?25h" 就可以了)std::cout << std::endl << "\033[?25h";
}

这个程序存在着一定的问题,如果是倒计时的话效果如图1-2所示:

图1-2

可以看到一开始输出了10,占两个字符位置,后面由于都是输出单字符的数字,所以10后面的那个0一直停留在那里独自抱窝。对程序进行完善修改如下:

#include <iostream>
#include <unistd.h>int count_bit(int number)
{int count = 1;while (number /= 10){count++;}return count;
}int main(int argc, char* argv[])
{// 设置为无缓冲setbuf(stdout, NULL);// 隐藏光标std::cout << "\033[?25l";int last_bit = 0;
#if 1for (int i = 1000000; i > 0; i /= 10)
#elsefor (int i = 1; i <= 10; i++)
#endif{int cur_bit = count_bit(i);std::cout << i;int dif = last_bit - cur_bit;if (dif > 0)std::cout << std::string(dif, ' ');std::cout << "\r";last_bit = cur_bit;sleep(1);}// 输出换行并恢复光标(光标不见了可以在终端执行 echo -e "\033[?25h" 就可以了)std::cout << std::endl << "\033[?25h";
}

这次来个跨度比较大的迭代输出,这样可以更加直观看到我们的程序已经修改正确,如图1-3所示:

图1-3

2、在文件中就地覆盖输出字符

前面做了一个在终端就地覆盖输出字符的程序,现在来探讨下在文件中就地覆盖字符该怎么做。首先,试试第一节那个方法可不可以直接使用,程序如下:

#include <iostream>
#include <fstream>
#include <unistd.h>int count_bit(int number)
{int count = 1;while (number /= 10){count++;}return count;
}int main(int argc, char* argv[])
{std::ofstream ofs("test", std::ios::out);if (!ofs){std::cout << "打开文件出错" << std::endl;return -1;}int last_bit = 0;
#if 1for (int i = 1000000; i > 0; i /= 10)
#elsefor (int i = 1; i <= 10; i++)
#endif{int cur_bit = count_bit(i);ofs << i;int dif = last_bit - cur_bit;if (dif > 0)ofs << std::string(dif, ' ');ofs << "\r";last_bit = cur_bit;sleep(1);}
}

输出文件内容如下:

1000000
100000
10000
1000
100
10
1

看来不能直接使用了,得另辟蹊径了。设计思路如下:

  1. 我们以读写的方式打开文件,如果文件不存在则创建(这里要注意不要用追加方式打开,不然就不能自由通过设置偏移量来达到对局部进行写入操作了,因为以追加打来文件之后写操作的偏移就失效了)
  2. 打开文件后,先把原先的内容记录下来(假设我们文件只有一行内容,记录着一个数字),然后对这个值进行各种操作(增加、减少都行)
  3. 操作完成之后,通过设置偏移量到文件开头,把数字写回去文件中,达到覆盖前面内容的目的

测试程序如下:

#include <iostream>
#include <fstream>
#include <unistd.h>int count_bit(long number)
{int count = 1;while (number /= 10){count++;}return count;
}int main(int argc, char* argv[])
{std::fstream f;f.open("test", std::ios::out | std::ios::in);if (!f.is_open()){f.open("test", std::ios::out | std::ios::in | std::ios::trunc);if (!f.is_open()){std::cout << "打开文件出错" << std::endl;return -1;}}std::string line;long number;if (std::getline(f, line) == 0){number = 1000000;std::cout << "第一次打开文件,设置初始值为1000000" << std::endl;}else{number = atol(line.c_str());std::cout << "打开文件成功,读取到的初始值为" << number << std::endl;}int last_bit = count_bit(number);// 这里自由发挥,加减乘除随便弄number /= 10;if (number == 0)number = 1000000;int cur_bit = count_bit(number);int dif = last_bit - cur_bit;// 清除流状态,必须加f.clear();f.seekp(0, std::ios::beg);f << number;if (dif > 0)f << std::string(dif, ' ');
}

这里就不贴结果图了,大家可以自行去尝试一下,就是简单地通过偏移写指针来达到往指定区域写入的内容的目的,这样也能覆盖掉原先的内容了。

3、总结

本文讲了两个简单的例子,第一个例子可以用作终端对某些操作进行倒计时或计数;第二个例子可以用于每天简单地记录某些批处理任务执行的次数,比如爬虫爬了多少内容之类的,当然其它语言大家就得按着这个思路自己去改改了。要注意这个也只能做点简单的记录了,复杂的记录还是得做一个规范的日志文件。

最后,如果大家觉得本文写得好的话麻烦点赞收藏关注一下谢谢,也可以关注该专栏,以后会有更多优质文章输出的。

C++在终端、文件中就地覆盖输出的方法相关推荐

  1. java基础IO流使用读取一个文件中的文字输出到控制台上

    读取一个文件中的文字输出到控制台上 import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IO ...

  2. python怎么横着输出_对python3中, print横向输出的方法详解

    对python3中, print横向输出的方法详解 Python 2 : print打印的时候,如果结尾有逗号,打出来时候不会换行.但是在python3里面就不行了. Python3: 3.0的pri ...

  3. python逐行写入csv_python 实现一次性在文件中写入多行的方法

    python 实现一次性在文件中写入多行的方法 将要写入的内容 构造 进一个list 中,使用writelines()方法 一次性写入. file_w.writelines(list) file_w. ...

  4. python读取字符串指定位置字符_python读取txt文件中特定位置字符的方法

    python读取txt文件中特定位置字符的方法 如下所示: # -*- coding:utf-8 -*- import sys reload(sys) sys.setdefaultencoding(' ...

  5. Android开发过程中在sh,py,mk文件中添加log信息的方法

    Android开发过程中在sh,py,mk文件中添加log信息的方法 在sh文件中: echo "this is a log info" + $info 在py文件中: print ...

  6. Python3实现从txt文件中读取指定行的方法

    Python3实现从txt文件中读取指定行的方法 本文实例讲述了Python3实现从文件中读取指定行的方法.分享给大家供大家参考.具体实现方法如下: def getline(the_file_path ...

  7. android 自定义view xml ,Android实现在xml文件中引用自定义View的方法分析

    本文实例讲述了Android实现在xml文件中引用自定义View的方法.分享给大家供大家参考,具体如下: 在xml中引用自定义view 方法一: android:layout_width=" ...

  8. 如何关闭linux系统中的覆盖输出重定向()功能

    一.问题描述               我们在进行文件操作时经常会用到覆盖输出重定向(>),追加输出重定向(>>),很明显的看出两种输出重定向的符号相差不是很大,但是两种的意义却又 ...

  9. 用python替换文件中内容的两种方法

    目标:替换文件中的字符串内容 方法1:使用fileinput包 import fileinput for line in fileinput.input("要修改的文件名", in ...

最新文章

  1. python >> 和 <<
  2. 中国顶级 AI 研究者数量仅为美国 1/5:美国智库最新全球 AI 实力报告
  3. Meditation Guide
  4. mfc exe 在繁体系统 乱码_MC32/MC92 自带TelnetCE界面部分字符乱码解决方案
  5. 吐血整理 | 肝翻 Linux 进程调度所有知识点|中奖揭晓
  6. 高级java开发_适用于高级Java开发人员的十大书籍
  7. 全班100名同学抽奖c语言,C语言综合设计实验-1-班级同学录程序设计.pptx
  8. sqlserver 登录名迁移
  9. 余额宝宣布开放 中欧基金首批入驻
  10. 【计算机组成原理】中央处理器(三)—— 数据通路
  11. 津巴布韦 apn_津巴布韦的回忆-你负担不起回家
  12. 腾讯微云下载慢解决办法
  13. 记录一次实战破解无线wifi——Aircrack-ng
  14. 2021-05-11 MongoDB面试题 MongoDB中的命名空间是什么意思
  15. 盘点国内优秀的机器人公司
  16. 神经网络中的对抗样本
  17. 16QAM调制解调系统误码率和星座图的matlab仿真
  18. Nomad集群 自身高可用测试
  19. 1218学习笔记——kvm上vm+vtpm(IMA)
  20. 珊珊来迟的解决方法——VB中防止多用户登录

热门文章

  1. antd日期选择组件a-range-picker默认选中的时分秒
  2. 关于Autosar中的NM模块的理解
  3. 中国移动云mas短信对接(http)
  4. Linux—添加开机启动
  5. moment 秒级时间戳转格式
  6. 如何利用宝塔面板+JavaWeb+MySQL设计一个注册登录界面
  7. 一个产品从0到1的完整流程
  8. 猜数字游戏 由计算机,猜数字游戏玩法
  9. python布尔系列_python-布尔运算
  10. Can‘t checkout because of unmerged files                 You have to resolve all merge conflicts bef