【Gizmos】#001 Copy的代码中有行号且去除麻烦?试试代码前缀“去质器“

【Gizmos】#001 Copy的代码中有行号且去除麻烦?试试代码前缀"去质器"

    • 1. 问题的引出
    • 2. 问题解决方案
    • 3. 代码实现
    • 4. 运行结果
    • 5. 不足之处
    • 写在最后

从今天开始,笔者将开启一个新板块——Gizmos(译为小发明或小物件),板块名称来源于Unity3D的一个小模块。该板块旨在分享一些实用小工具,它们往往是轻量且简洁的,是笔者对于日常生活进行观察后获得的灵感,然后通过编码将自己的Idea实现。要说明的是,这种实现很大可能不是最优的,总会存在这样那样的局限性,

1. 问题的引出

作为21世纪的人,比如看到这篇文章的你(您),总有需要"借鉴"别人代码的时候,这时候可能就会去CSDN,博客园等去找寻,然后使用无敌的“CV”大法占为己有。这不,笔者今天正想着入门OpenCV,配置好OpenCV的环境后,在CSDN上CV了如下代码,用以测试环境配置是否成功:

1.  #include <opencv2\opencv.hpp> //加载OpenCV 4.1头文件
2.  #include <iostream>
3.
4.  using namespace std;
5.  using namespace cv; //opencv的命名空间
6.
7.  int main()
8. {9.    Mat img; //声明一个保存图像的类10.    img = imread("G:/opencv/lena.png"); //读取图像,根据图片所在位置填写路径即可11.    if (img.empty()) //判断图像文件是否存在12.    {13.      cout << "请确认图像文件名称是否正确" << endl;14.      return -1;15.    }16.    imshow("test", img); //显示图像17.    waitKey(0); //等待键盘输入18.    return 0; //程序结束19.  }

观察上面代码,发现每行开头总有序号,代码不长时倒还好,可以一个个去掉,但当行数上百、上千甚至上万时,手动去除可就不妙了。

笔者是个懒人,即便copy的代码不到20行,也不想手动完成这种琐事,于是花了近1小时来实现、调试、完善和泛化行号去除的功能。用程序处理后的代码文本如下:

  #include  //加载OpenCV 4.1头文件#include using namespace std;using namespace cv; //opencv的命名空间int main(){Mat img; //声明一个保存图像的类img = imread("G:/opencv/lena.png"); //读取图像,根据图片所在位置填写路径即可if (img.empty()) //判断图像文件是否存在{cout << "请确认图像文件名称是否正确" << endl;return -1;}imshow("test", img); //显示图像waitKey(0); //等待键盘输入return 0; //程序结束}

2. 问题解决方案

问题描述: 给定一个文本文件,其中每一行的开头都可能有(或没有)序号,序号形式通常为xxx.xxx:等,请读取文本文件,去除文本文件中每一行开始的序号,将运行结果保存在另一个文件中。

解决方案通过C/C++的文件操作逐行读取字符串,去除其中的序号后再逐行输出到保存文件中。去除序号的关键特征为分隔符".",考虑到分隔符的多样性,这里交由用户来决定,即在文件的第一行输入分隔符,但考虑很多情况下序号的分隔符就是".",而且用户更倾向于把代码贴到文本文件中就完事了。为了便利起见,笔者设默认分隔符为"."。这样,即便用户没有在第一行输入分隔符,程序也能正常进行。

关于程序的使用步骤和其余细节,尤其是文件的输入部分(fscanf()fgets()),详见代码实现。

3. 代码实现

/*
根据分隔符去除文本的前缀部分
例如:chsplit = '.'时,代表将文本文件中每一行第一个'.'及之前的所有字符滤去
====================使用说明==================== 
1. 使用前,先创建名为data_in.txt的文本文件; 
2. 在文本第一行,填写特征分隔符,比如,你要去掉每行代码的序号"xxx.",
此时你就在第一行写'.',程序将把每行第一个'.'及之前的字符去除(第一行只能有一个字符); 
3. 在第一行后粘贴需要修改的代码,保存并关闭文件;
4. 运行代码生成的.exe文件,运行结果保存在了data_out.txt中。 Author: 圣☆哥
E-Mail: a2540588513@stu.xjtu.edu.cn
IDE: DevCpp5.4.0 
Create Date:2021/12/14
Update Date:2021/12/14
CSDN Blog: https://me.csdn.net/weixin_42430021
*/#include 
#include 
#include
#include
#define maxn 1005
char buff[maxn];
using namespace std;// 检查buff中是否只有一个非空字符 
bool checkOneChar(){int n = strlen(buff);int cnt = 0;for (int i=0; i<n; ++i){if(buff[i] != ' '){cnt++;if(cnt > 1)return false;}}return cnt == 1;
}int main(){FILE* fin = NULL;FILE* fout = NULL;char chsplit='.'; fin = fopen("./data_in.txt", "rb");fout = fopen("./data_out.txt", "wb");if(!fin){printf("data_in.txt read error. Please check if the name of text file is correct\n");getchar();exit(-1);}if(!fout){printf("data_out.txt write error.""Please insure the file is not occupied by other process.\n");		getchar();exit(-1);}fscanf(fin, "%s", buff);while (fgetc(fin) != '\n') continue; // 滤去换行符 if(!checkOneChar()){ // 第一行有且仅有一个字符 printf("Warning: The first line of data_in.txt must be one character for left striping.\n""I assume that you want to use \'.\' to left strip the text file.\n");rewind(fin);}else{chsplit = buff[0];}while (fgets(buff, maxn, fin)){string s(buff);fprintf(fout, "%s", s.substr(s.find_first_of(chsplit)+1).c_str());}fclose(fin);fclose(fout);printf("Done!\n");getchar();return 0;
}

4. 运行结果

这里就把输入和输出文件展示一下,注意输入文件的命名是固定的data_in.txt

在这里插入图片描述

5. 不足之处

  1. 只能处理前缀;

  2. 只是以单字符为特征来分割字符串,不过考虑到应用场景主要是代码的序号去除,这不是啥大问题;

  3. 没有考虑代码的对齐,这个步骤笔者就暂时交由编辑器实现了;

  4. 其余笔者没有想到的、潜在的bug和不足…

写在最后

我想每个程序员都应该有着 “To be a Dream Weaver” 这样的理想,即能够将任何理论可行的想法变成现实,虽然这么说很夸张,毕竟人的精力有限,“术业有专攻”,但是,人要有梦想嘛。

“总有一天,我要成为神奇宝贝大师” —— 小智

笔者水平有限,欢迎批评指正~


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部