从今天开始,笔者将开启一个新板块——Gizmos(译为小发明或小物件),板块名称来源于Unity3D的一个小模块。该板块旨在分享一些实用小工具,它们往往是轻量且简洁的,是笔者对于日常生活进行观察后获得的灵感,然后通过编码将自己的Idea实现。要说明的是,这种实现很大可能不是最优的,总会存在这样那样的局限性,
作为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; //程序结束
}
问题描述: 给定一个文本文件,其中每一行的开头都可能有(或没有)序号,序号形式通常为xxx.
,xxx:
等,请读取文本文件,去除文本文件中每一行开始的序号,将运行结果保存在另一个文件中。
解决方案:通过C/C++的文件操作逐行读取字符串,去除其中的序号后再逐行输出到保存文件中。去除序号的关键特征为分隔符"."
,考虑到分隔符的多样性,这里交由用户来决定,即在文件的第一行输入分隔符,但考虑很多情况下序号的分隔符就是"."
,而且用户更倾向于把代码贴到文本文件中就完事了。为了便利起见,笔者设默认分隔符为"."
。这样,即便用户没有在第一行输入分隔符,程序也能正常进行。
关于程序的使用步骤和其余细节,尤其是文件的输入部分(fscanf()
和fgets()
),详见代码实现。
/*
根据分隔符去除文本的前缀部分
例如:chsplit = '.'时,代表将文本文件中每一行第一个'.'及之前的所有字符滤去
====================使用说明====================
1. 使用前,先创建名为data_in.txt的文本文件;
2. 在文本第一行,填写特征分隔符,比如,你要去掉每行代码的序号"xxx.",
此时你就在第一行写'.',程序将把每行第一个'.'及之前的字符去除(第一行只能有一个字符);
3. 在第一行后粘贴需要修改的代码,保存并关闭文件;
4. 运行代码生成的.exe文件,运行结果保存在了data_out.txt中。
Author: 圣☆哥
E-Mail: [email protected]
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;
}
这里就把输入和输出文件展示一下,注意输入文件的命名是固定的data_in.txt
:
只能处理前缀;
只是以单字符为特征来分割字符串,不过考虑到应用场景主要是代码的序号去除,这不是啥大问题;
没有考虑代码的对齐,这个步骤笔者就暂时交由编辑器实现了;
其余笔者没有想到的、潜在的bug和不足…
我想每个程序员都应该有着 “To be a Dream Weaver” 这样的理想,即能够将任何理论可行的想法变成现实,虽然这么说很夸张,毕竟人的精力有限,“术业有专攻”,但是,人要有梦想嘛。
“总有一天,我要成为神奇宝贝大师” —— 小智
笔者水平有限,欢迎批评指正~