前言
今天咱们做一点有意思的事情,平时我们批量修改txt文件中的内容,首先想到的就是写一个python小程序才批量修改txt文件内容,那么C++能办到么?当然可以!只不过C++要比python麻烦很多,毕竟python一行代码解决的事情,背后可能就是C++的一个函数体,但是为了学习C++,我们还是姑且看一下吧!其实用C++写一下也是一件很有意思的事情,并且也能学到很多东西!
1.首先是需要提供的库文件
#include <io.h>
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
2.获取特定格式文件
void GetAllFormatFiles( string path, vector<string>& files,string format)
{
long hFile = 0;
struct _finddata_t fileinfo;
string p;
if((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(),&fileinfo)) != -1)
{
do
{
if((fileinfo.attrib & _A_SUBDIR))
{
if(strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0)
{
GetAllFormatFiles( p.assign(path).append("\\").append(fileinfo.name), files,format);
}
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
}
}while(_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
这个便是获取特定格式的文件名的函数体啦! 不要着急!咱们慢慢看,慢慢分析!
1. 首先是看参数列表:
(1)需要提供文件夹的路径(2)一个保存文件名的string格式的vector容器(3)一个"format"字符串,也就是你要找什么格式的文件,比如(.txt)格式的文件!
2. 文件句柄
再就是文件句柄,句柄是什么呢?百度百科告诉我们,句柄是这样子的:句柄是Windows系统中对象或实例的标识,这些对象包括模块、应用程序实例、窗口、控制、位图、GDI对象、资源、文件。从数据类型上来看:它只是一个16位的无符号整数。
也就是说:句柄差不多可以理解为一个指针就可以了,句柄就是文件的标识而已。它的数据存储格式是16位的无符号整数。
3. 文件信息
struct _finddata_t fileinfo;
这个 fileinfo 的含义我也不太清楚,我姑且就把它当做是可以读取到文件夹的所有的文件信息了。
接着就利用_findfirst函数看 路径文件夹下 是否有对应格式的文件。也就是第一个if语句的功能。 来深度解析一下这句话,p是一个字符串,那么p.assign(path).append("\*" + format)其实就是将文件夹路径在加上特定的文件格式。比如p可以是:"C:/Users/10123/Desktop/python*.txt。后面加一个.c_str()意思就是,返回了一个指向p字符串的可读不可修改常量指针。
_findfirst函数功能是搜索与指定的文件名称匹配的第一个实例,若成功则返回第一个实例的句柄,否则返回-1L。 也就是说,看fileinfo里面是否有txt格式的文件,有就返回该文件的句柄。
(hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(),&fileinfo)) != -1
这句代码首先是先_findfirst搜索,然后将返回的结构赋值hFile,然后再将hFile与-1做不等比较。
如果文件夹内有对应的文件时, _findfirst函数,返回句柄数(肯定不是-1)那么hFile赋值为该句柄。接着,条件 != -1 为真,可以进入if条件内。也就是说,文件内有txt格式文件,才能进入if 。否则,进else。
4. 第二个if(do-while循环内)
接着,当有文件时,进入if了,进入了do-while循环。到了第二个if。
if((fileinfo.attrib & _A_SUBDIR)) 这句话是比较文件类型是否是文件夹 attrib,就是所查找文件的属性:__A_ARCH(存档)、_A_HIDDEN(隐藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、 _A_SUBDIR(文件夹)、_A_SYSTEM(系统)。
如果文件夹内部还有文件夹,就依次对该目录下的所有子文件夹都遍历找 含有该格式的文件。
else: 如果不是文件夹了,那当前的fileinfo肯定就是我们要找的文件的fileinfo了,这时候,将文件名(fileinfo.name)加入我们的vector容器内,做保存就可以了。
do-while循环的条件为:
_findnext(hFile, &fileinfo) == 0
这里,_findnext函数的作用是搜索与_findfirst函数提供的文件名称匹配的下一个实例,若成功则返回0,否则返回-1。
也就是在搜索与txt格式匹配的下一个实例(排除掉已经搜索过的实例)。(算是完成接续遍历了)
最后不要忘记_findclose(hFile)就可以了。
以上就是大致C++遍历读取文件夹下特定格式的文件的所有内容了。在贴上一份对txt文件处理的main函数代码。
int main()
{
string filePath = "C:/Users/10123/Desktop/python/txt";
vector<string> files;
string format = ".txt";
GetAllFormatFiles(filePath, files,format);
int size = files.size();
for (int i = 0;i<size;i++)
{
ifstream in(files[i]);
string filename;
string line;
string newline;
string allline;
if(in)
{
while (getline (in, line))
{
newline = '0' + line.substr(1,line.size()-1)+'\n';
allline +=newline;
}
allline.erase(allline.size()-1,1);
ofstream out;
out.open(files[i],ios::out);
out << allline;
out.close();
}
else
{
cout <<"no such file" << endl;
}
}
return 0;
}
该main函数的功能是 将txt文件中的每一行的第一个字符改成0,其他不变。并且改过之后的txt文件最后不多余一个换行符!
|