【Fsteam】使用C++筛选合并多文件的尝试

今天接到一个小任务,说是让把好多文件(大概2800来个,总大小超过1G)中的信息进行筛选,整合到一个文件里方便接下来的操作。
那么,无可避免的就需要用到多文件读写。那么,该如何批量打开多个文件进行读写操作呢?
众所周知 freopen(filename,r/w,i/ostream)的第一个参数filename需要是一个常量const char*,即便文件名是有序的,我们也没办法将变量传参进去。

于是,在搜索与自学中看到了这样一个实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int i;
char filename[30],line[1001];
ifstream File[5];
ofstream File2;
File2.open("5.txt",ios::out);
for(i=1;i<5;i++)
{
sprintf(filename,"%d.txt",i);
File[i].open(filename,ios::in);
while(!File[i].eof())
{
File[i].getline(line,1000);
File2<<line<<endl;
}
File[i].close();
}
File2.close();
system("pause");
return 0;
}

用数组来申明文件输入输出流,使用正规的fsream函数来进行操作,简单易懂而且操作高效。
然而,关于当前文件夹究竟有哪些文件,也懒得一一输入进来,于是我们又需要这样一个函数来获得某个文件夹内,所有文件的名称(获得之后也可以通过文件读写把所有文件名写入一个文件中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include<iostream>
#include<vector>
using namespace std;
int main(int argc, char *argv[])
{
DIR *dp;
struct dirent *dirp;
vector<std::string> filename;
if( (dp=opendir("F:\\directory_name") )==NULL )
perror("open dir error");

while( (dirp=readdir(dp) )!=NULL )
filename.push_back(dirp->d_name);
for(int i=0;i<filename.size();i++)
cout<<filename[i]<<endl;
closedir(dp);
return 0;
}

在掌握了这些之后,尝试着写了一个较大的程序,实现的工程应用如下:从CN-pair中获得事先输出的键值对,存储在缓存中,接着对大数量的文件进行读取,每行三列以’\t’分割的数据经过处理,获得第二列中的数据,筛去的值,依次存储于文件SUM中,与其相对应的频数则也依次存储于FREQ中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <map>
#include <cmath>
#include <vector>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;

#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))

bool cmp(const int a, const int b)
{
return a > b;
}

map<string,string> mark;
vector<int> freq;

void get_CNpair() //get <Code-Name> pair into Cache
{
string c,n;
mark.clear();
freopen("CN-pair","r",stdin);
while(cin>>c>>n) mark[c]=n;
fclose(stdin);
}

int IncludeChinese(char *str) //0: English 1:Chinese
{
char c;
while(1)
{
c=*str++;
if (c==0) break;
if (c&0x80)
if (*str & 0x80) return 1;
}
return 0;
}

int main()
{
get_CNpair();
freq.clear();
char filename[30],line[1024],t[1024];
ifstream File[3333];
ofstream File2;
File2.open("Sum.txt",ios::out);
int i=1;
for(map<string,string>::iterator mit=mark.begin();mit!=mark.end();++mit,++i)
{
//cout<<mit->first<<":"<<mit->second<<endl;
char addr[6];
for(int j=0;j<6;j++) addr[j]=(mit->first)[j];
sprintf(filename,"%s",addr);
File[i].open(filename,ios::in);
//File2<<"#"<<mit->first<<"#"<<endl;
while(!File[i].eof())
{
File[i].getline(line,1023);
string anti=line;
int flag=0,rj=0,temp=0;
for(int ri=0;ri<strlen(line);ri++)
{
if(flag==0 && line[ri]=='\t') {flag=1;continue;}
if(flag==0) continue;
if(line[ri]=='\t')
{
temp=0;
ri++;
while(line[ri]!='.')
{
temp=temp*10+(int)(line[ri]-'0');
ri++;
} break;
}
else
{
if(line[ri]!=32 && line[ri]>0 && line[ri]<127);
else if(isdigit(line[ri]));
else t[rj++]=line[ri];
}
}
t[rj]='\0';
if(strlen(t)>0 && IncludeChinese(t))
{
string t_str=t,
rpls1=mit->first,
rpls2=mit->second;
//cout<<rpls1<<rpls2<<endl;
if(t_str.find(rpls1)!=t_str.npos)
t_str=t_str.replace(t_str.find(rpls1),rpls1.length(),"");
//cout<<"rpls1:"<<t_str<<":"<<rpls1<<endl;
if(t_str.find(rpls2)!=t_str.npos)
t_str=t_str.replace(t_str.find(rpls2),rpls2.length(),"");
//cout<<"rpls2:"<<t_str<<":"<<rpls2<<endl;

if(t_str.length()>0)
{
bool blank_flag=1;
for(int bi=0;bi<t_str.length();bi++)
{
if(t_str[bi]!=' ')
{
blank_flag=0;
break;
}
}
if(blank_flag)
{
File2<<line<<endl;
freq.push_back(temp);
}
}
}
}
File[i].close();
}
File2.close();
freopen("freq.txt","w",stdout);
//for(vector<int>::iterator vd=freq.begin();vd!=freq.end();++vd)
for(int i=0;i<freq.size();i++)
cout<<freq[i]<<endl;
fclose(stdout);
return 0;
}