关于C/C++的txt文本文件提取问题,请指教!

lemontree197977 2010-04-30 01:54:33
最近用到文本文件提取的问题,现有文本文件a.txt信息格式如下:

$WFE,1000.0440,W,09000.0000,Y,X,X,AA6
9980,0000043,0003440,040,040,040,002,023,030
8000,0054500,0005640,050,040,040,030,003,030
8596,0076700,0006340,300,450,023,230,300,030
5678,0004556,0045600,600,400,050,034,030,300
5665,4353000,0232434,340,034,045,320,030,200
.
.
.
$WFE,1000.0440,W,09000.0000,Y,X,X,AA6
9980,0000043,0003440,040,040,040,002,023,030
8000,0054500,0005640,050,040,040,030,003,030
8596,0076700,0006340,300,450,023,230,300,030
5678,0004556,0045600,600,400,050,034,030,300
5665,4353000,0232434,340,034,045,320,030,200

我想以将数据以","分隔提取a1~a53个字符数组,并且输出到b.txt文件,

我简单的的叙述方法:我想将每6行文件替换掉其中的换行符"\n",并写入到一个temp.txt文件,然后用fscanf方法取出字段至a1~a53,然后可

以提取任意相关字段至b.txt

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#include <windows.h>
#include <stdio.h>

#define MAX_NUM 300
#define NUM 9

int main()
{

char FileName_a[MAX_NUM] = "D:/工作区/C/a.txt";
char FileName_b[MAX_NUM] = "D:/工作区/C/b.txt";
char FileName_temp[MAX_NUM] = "D:/工作区/C/temp.txt";

char Buffer[45] = "";
char Str_data[MAX_NUM] = "";
int i,j=0;

FILE* Soure = NULL;
FILE* Mid = NULL;
FILE* Dest = NULL;


Soure = fopen(FileName_a,"r");
if(Soure == NULL)
{
printf("Failed to open File %s\n",FileName_a);
}

Dest = fopen(FileName_b,"w+");
if (Dest == NULL)
{
printf("Failed to Open File %s\n",FileName_b);
}

//*
char a1[NUM] = "";
char a2[NUM] = "";
char a3[NUM] = "";
char a4[NUM] = "";
char a5[NUM] = "";
char a6[NUM] = "";
char a7[NUM] = "";
char a8[NUM] = "";
char a9[NUM] = "";
char a10[NUM] = "";
char a11[NUM] = "";
char a12[NUM] = "";
char a13[NUM] = "";
char a14[NUM] = "";
char a15[NUM] = "";
char a16[NUM] = "";
char a17[NUM] = "";
char a18[NUM] = "";
char a19[NUM] = "";
char a20[NUM] = "";
char a21[NUM] = "";
char a22[NUM] = "";
char a23[NUM] = "";
char a24[NUM] = "";
char a25[NUM] = "";
char a26[NUM] = "";
char a27[NUM] = "";
char a28[NUM] = "";
char a29[NUM] = "";
char a30[NUM] = "";
char a31[NUM] = "";
char a32[NUM] = "";
char a33[NUM] = "";
char a34[NUM] = "";
char a35[NUM] = "";
char a36[NUM] = "";
char a37[NUM] = "";
char a38[NUM] = "";
char a39[NUM] = "";
char a40[NUM] = "";
char a41[NUM] = "";
char a42[NUM] = "";
char a43[NUM] = "";
char a44[NUM] = "";
char a45[NUM] = "";
char a46[NUM] = "";
char a47[NUM] = "";
char a48[NUM] = "";
char a49[NUM] = "";
char a50[NUM] = "";
char a51[NUM] = "";
char a52[NUM] = "";
char a53[NUM] = "";

while((fgets(Buffer,MAX_NUM,Soure) != NULL)&&(!feof(Soure)))
{
if (i<6)
{
//每六行数据生成一数组
i++;
printf("%d",i);
strcat(Str_data,Buffer);
//strcat(Str_data,",");
}
else
{
//清空数据中的换行符
for(j=0;j<300;j++)
{
if (Str_data[j]=='\n')
{
Str_data[j]=',';
}
}
printf("%s",Str_data);
//重新生成中转文件,并写入数据
Mid=fopen(FileName_temp,"w+");
fprintf(Mid,"%s",Str_data);
fclose(Mid);
//读取中转文件中的数据
Mid1=fopen(FileName_temp,"r+");
fscanf(Mid1,"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%

s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%

s,\n",a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,

a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53);
fclose(Mid1);
//写入目标文件
fprintf(Dest,"%s %s\n",a1,a2);
fclose(Mid);

//重新将计数及数组清空,以便接收新的数据
i=0;
for(j=0;j<300;j++)
{
Str_data[j]=NULL;
}
}
fclose(Soure);
fclose(Dest);

return 0;
}

##############################################
虽然代码写完但是并没有我想要的结果,不知道问题出在哪里?!
另外,有没有更简单更好的方法用C或者C++来实现,最好有代码例程,谢谢各位了!!
####################################
...全文
586 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2010-05-05
  • 打赏
  • 举报
回复
记不得哪位C++大牛在哪本学习C++的书的前言里面说过
“用C语言1000行源码能完成的工作千万不要用C++重写!”
赵4老师 2010-05-05
  • 打赏
  • 举报
回复
光说不练,假把式。
//文本文件a.txt信息格式如下:
//$WFE,1000.0440,W,09000.0000,Y,X,X,AA6
//9980,0000043,0003440,040,040,040,002,023,030
//8000,0054500,0005640,050,040,040,030,003,030
//8596,0076700,0006340,300,450,023,230,300,030
//5678,0004556,0045600,600,400,050,034,030,300
//5665,4353000,0232434,340,034,045,320,030,200
// .
// .
// .
//$WFE,1000.0440,W,09000.0000,Y,X,X,AA6
//9980,0000043,0003440,040,040,040,002,023,030
//8000,0054500,0005640,050,040,040,030,003,030
//8596,0076700,0006340,300,450,023,230,300,030
//5678,0004556,0045600,600,400,050,034,030,300
//5665,4353000,0232434,340,034,045,320,030,200
//
//将数据以","分隔提取a1~a53个字符数组,并且输出到b.txt文件,
#include <string.h>
#include <stdio.h>
char a[53][20];
char ln[80];
char seps[] = ",\n";
char *token;
FILE *fa,*fb;
int i;
void main() {
fa=fopen("a.txt","r");
fb=fopen("b.txt","w");
i=0;
while (1) {
fgets(ln,80,fa);
if (feof(fa)) break;
token=strtok(ln,seps);
while (token!=NULL) {
strcpy(a[i],token);
if (i==52) {
fprintf(fb,"%s\n",a[i]);
i=0;
} else {
fprintf(fb,"%s,",a[i]);
i++;
}
token = strtok( NULL, seps );
}
}
fclose(fb);
fclose(fa);
}
everbeing 2010-05-05
  • 打赏
  • 举报
回复
老是掉点东西,以后不贴code了


#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<vector>
using namespace std;
typedef unsigned int Group ;

//将str中含rsch的字符换成dsch字符,并返回替换后的副本
string Replace(size_t ipos,string str,char rsch,char dsch);

//判断i是否在数组npos中
bool isPostive(int i,int npos[],size_t size);

//传递一个打开的文件流和组i,和npos数组,size记录npos长度
vector<string> getElems(ifstream& infile,Group i,int npos[],size_t size);

//打印svec中的信息
void PrintInfo(ostream& os,const vector<string>& svec);

//传递写入文件流,eachline_no设置每行元素个数,svec为写入源,seperate为元素间分隔符
void Write(ofstream& out,size_t eachline_no,const vector<string>& svec,char seperate=' ');

int main()
{
char *fileName="H:\\1.txt";//设置关联文件名
ifstream infile(fileName);
if(!infile.is_open()) cerr<<"open file error!"<<endl;

vector<string> svec;
Group group=1; //设置组//索引从1开始
int npos[]={1,2,4,8,10,22,13,16,17,19,20,29};//得到第一组 a1 a2 a4 //索引从1开始
svec=getElems(infile,group,npos,sizeof(npos)/sizeof(*npos));//得到信息
PrintInfo(cout,svec); //屏幕上打印信息
infile.close();

ofstream outfile("H:\\2.txt",ios::app);
if(!outfile.is_open()) cerr<<"open file error!"<<endl;
Write(outfile,9,svec,',');//写入文件
outfile.close();
return 0;
}













///////////////////////////////////////////////////////////////////
bool isPostive(int i,int npos[],size_t size) //判断i是否在数组npos中
{
int index=0;
while(index!=size){
if(i==*(npos+index)) return true;
index++;
}
return false;

}
string Replace(size_t ipos,string str,char rsch,char dsch)//将str中含rsch的字符换成dsch字符,并返回替换后的副本
{
while(ipos<str.length()){
if(str[ipos]==rsch) str[ipos]=dsch;
ipos++;
}
return str;
}
//i标志所在组,npos标注要返回该组那些元素 ,size标注npos数组长度
vector<string> getElems(ifstream& infile,Group i,int npos[],size_t size)//传递一个打开的文件流和组i,和npos数组,size记录npos长度
{
size_t index=0,line_no=i*6; //组与所在记事本所在行的转换
string temp,str;
size_t line=i-1;
vector<string> svec;
while(line&&getline(infile,temp)){//用文件流进行 行 读取,读取到第i行(找到组”基地址")
line--;
}
if(i==0) return svec; //组不正确,返回一个空string组(包含sstream头文件

line=6; //重新设置line用str读入一个组

while(line--&&getline(infile,temp)){
str+=" "+temp;
}
cout<<str<<endl;
str=Replace(0,str,',',' ');//将该组所有‘,’替换成‘ ’
stringstream strLine(str);//定义一个字符串流

index=0;
while(strLine>>str){
if(isPostive(++index,npos,size))//查看该计数出的字符串时候是想要得到的
svec.push_back(str); //svec加载
}
return svec;
}

void PrintInfo(ostream& os,const vector<string>& svec)
{
if(!svec.empty())
{
vector<string>::const_iterator con_it=svec.begin();
while(con_it!=svec.end())
os<<*con_it++<<" ";
}
cout<<endl;
}
void Write(ofstream& out,size_t eachline_no,const vector<string>& svec,char seperate)
{
if(!svec.empty()){
vector<string>::const_iterator con_it=svec.begin();
while(con_it!=svec.end()){
out<<*con_it++<<seperate;
if(--eachline_no) out<<'/n';//换行
}
out<<'/n';
}
}




jzd19851102 2010-05-05
  • 打赏
  • 举报
回复
对我有用 顶一下
everbeing 2010-05-05
  • 打赏
  • 举报
回复
//上面的getElems只能得到任意一组同行级的元素(没注意) 现替换成下面的getElems久
//可以完全得到“任意一个组”的“任意多个元素”了
vector<string> getElems(ifstream& infile,Group i,int npos[],size_t size){
size_t index=0,line_no=i*6; //组与所在记事本所在行的转换
string temp,str;
size_t line=i-1;
vector<string> svec;
while(line--&&getline(infile,temp)){//用文件流进行 行 读取,读取到第i行(找到组”基地址")
if(line=i) break;//终止
}
if(i==0) return svec; //组不正确,返回一个空string组(包含sstream头文件

line=6; //重新设置line用str读入一个组

while(line--&&getline(infile,temp)){
str+=" "+temp;
}
str=Replace(0,str,',',' ');//将该组所有‘,’替换成‘ ’
stringstream strLine(str);//定义一个字符串流

index=0;
while(strLine>>str){
if(isPostive(index++,npos,size))//查看该计数出的字符串时候是想要得到的
svec.push_back(str); //svec加载
}
return svec;
}
everbeing 2010-05-05
  • 打赏
  • 举报
回复



#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<vector>
using namespace std;
typedef unsigned int Group ;

//将str中含rsch的字符换成dsch字符,并返回替换后的副本
string Replace(size_t ipos,string str,char rsch,char dsch);

//判断i是否在数组npos中
bool isPostive(int i,int npos[],size_t size);

//传递一个打开的文件流和组i,和npos数组,size记录npos长度
vector<string> getElems(ifstream& infile,Group i,int npos[],size_t size);

//打印svec中的信息
void PrintInfo(ostream& os,const vector<string>& svec);



int main()
{
char *fileName="H:\\1.txt";//设置关联文件名
ifstream infile(fileName);
if(!infile.is_open()) cerr<<"open file error!"<<endl;

vector<string> svec;
Group group=1; //设置组
int npos[]={1,2,4};//得到第一组 a1 a2 a4 //索引从0开始
svec=getElems(infile,group,npos,sizeof(npos)/sizeof(*npos));//得到信息
PrintInfo(cout,svec); //打印信息

return 0;
}

bool isPostive(int i,int npos[],size_t size) //判断i是否在数组npos中
{
int index=0;
while(index!=size){
if(i==*(npos+index)) return true;
index++;
}
return false;

}
string Replace(size_t ipos,string str,char rsch,char dsch)//将str中含rsch的字符换成dsch字符,并返回替换后的副本
{
while(ipos<str.length()){
if(str[ipos]==rsch) str[ipos]=dsch;
ipos++;
}
return str;
}
//i标志所在组,npos标注要返回该组那些元素 ,size标注npos数组长度
vector<string> getElems(ifstream& infile,Group i,int npos[],size_t size)//传递一个打开的文件流和组i,和npos数组,size记录npos长度
{
size_t index=0,line_no=i*6; //组与所在记事本所在行的转换
string str;
size_t line=i;
vector<string> svec;
while(line--&&getline(infile,str)){//用文件流进行 行 读取,读取到第i行
if(line=i) break;//终止
}

if(i==0) return svec; //组不正确,返回一个空string组(包含sstream头文件
str=Replace(0,str,',',' ');//将‘,’替换成‘ ’
stringstream strLine(str);//定义一个字符串流

index=0;
while(strLine>>str){
if(isPostive(index++,npos,size))//查看该计数出的字符串时候是想要得到的
svec.push_back(str); //svec加载
}
return svec;
}

void PrintInfo(ostream& os,const vector<string>& svec)
{
if(!svec.empty())
{
vector<string>::const_iterator con_it=svec.begin();
while(con_it!=svec.end())
os<<*con_it++<<" ";
}
cout<<endl;
}








everbeing 2010-05-05
  • 打赏
  • 举报
回复
得到任意组合
$WFE,1000.0440,W,09000.0000,Y,X,X,AA6
9980,0000043,0003440,040,040,040,002,023,030
8000,0054500,0005640,050,040,040,030,003,030
8596,0076700,0006340,300,450,023,230,300,030
5678,0004556,0045600,600,400,050,034,030,300
5665,4353000,0232434,340,034,045,320,030,200
$WFE,1000.0440,W,09000.0000,Y,X,X,AA6
9980,0000043,0003440,040,040,040,002,023,030
8000,0054500,0005640,050,040,040,030,003,030
8596,0076700,0006340,300,450,023,230,300,030
5678,0004556,0045600,600,400,050,034,030,300
5665,4353000,0232434,340,034,045,320,030,200
比如得到 第一组 a1,a2,a4

结果为: 1000.0440 w Y

源码:(未做参数传入安全判断....)

#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<vector>
using namespace std;
typedef unsigned int Group ;

//将str中含rsch的字符换成dsch字符,并返回替换后的副本
string Replace(size_t ipos,string str,char rsch,char dsch);

//判断i是否在数组npos中
bool isPostive(int i,int npos[],size_t size);

//传递一个打开的文件流和组i,和npos数组,size记录npos长度
vector<string> getElems(ifstream& infile,Group i,int npos[],size_t size);

//打印svec中的信息
void PrintInfo(ostream& os,const vector<string>& svec);



int main()
{
char *fileName="H:\\1.txt";//设置关联文件名
ifstream infile(fileName);
if(!infile.is_open()) cerr<<"open file error!"<<endl;

vector<string> svec;
Group group=1; //设置组
int npos[]={1,2,4};//得到第一组 a1 a2 a4 //索引从0开始
svec=getElems(infile,group,npos,sizeof(npos)/sizeof(*npos));//得到信息
PrintInfo(cout,svec); //打印信息

return 0;
}

bool isPostive(int i,int npos[],size_t size) //判断i是否在数组npos中
{
int index=0;
while(index!=size){
if(i==*(npos+index)) return true;
index++;
}
return false;

}
string Replace(size_t ipos,string str,char rsch,char dsch)//将str中含rsch的字符换成dsch字符,并返回替换后的副本
{
while(ipos<str.length()){
if(str[ipos]==rsch) str[ipos]=dsch;
ipos++;
}
return str;
}
//i标志所在组,npos标注要返回该组那些元素 ,size标注npos数组长度
vector<string> getElems(ifstream& infile,Group i,int npos[],size_t size)//传递一个打开的文件流和组i,和npos数组,size记录npos长度
{
size_t index=0,line_no=i*6; //组与所在记事本所在行的转换
string str;
size_t line=i;
vector<string> svec;
while(line--&&getline(infile,str)){//用文件流进行 行 读取,读取到第i行
if(line=i) break;//终止
}

if(i==0) return svec; //组不正确,返回一个空string组(包含sstream头文件
str=Replace(0,str,',',' ');//将‘,’替换成‘ ’
stringstream strLine(str);//定义一个字符串流

index=0;
while(strLine>>str){
if(isPostive(index++,npos,size))//查看该计数出的字符串时候是想要得到的
svec.push_back(str); //svec加载
}
return svec;
}

void PrintInfo(ostream& os,const vector<string>& svec)
{
if(!svec.empty())
{
vector<string>::const_iterator con_it=svec.begin();
while(con_it!=svec.end())
os<<*con_it++<<" ";
}
cout<<endl;
}




yyg990441 2010-05-05
  • 打赏
  • 举报
回复
咳,想多了,还是用C风格的int*,int size传递数组比较好,我原来想把
class Data写成模板...就是为了将数组作为一个参数传递进去,现在想想还是指针+size两个参数传递比较好
yyg990441 2010-05-05
  • 打赏
  • 举报
回复
关于如何把表示第几列(列数从0开始计算)的int数组传进去的地方搞得有点恶心...今天没空了,先这样吧

#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<algorithm>
#include<limits>
using namespace std;
class Data;
istream &operator>>(istream& in,Data& d);
ostream &operator<<(ostream& o,const Data& d);

#define N 3
class Data{
int (&v)[N];
vector<string> svec;
public:
Data(int (&vec)[N]):v(vec){}
friend istream &operator>>(istream& in,Data& d);
friend ostream &operator<<(ostream& o,const Data& d);
};
istream &operator>>(istream& in,Data& d){
d.svec.clear();
string tmp,info;
for(int i=0;i<6;++i) {getline(in,tmp);info+=tmp+',';}
for(istringstream isstr(info);getline(isstr,tmp,',');)
d.svec.push_back(tmp);
return in;
}
ostream &operator<<(ostream& o,const Data& d){
for(int i=0;i<N;++i)
o<<d.svec[d.v[i]]<<' ';
return o;
}

int main(){
int s[N]={0,8,17};
Data d(s);
ifstream in("data.txt");
ofstream out("result.txt");
while(in>>d) out<<d<<endl;
}
lemontree197977 2010-05-04
  • 打赏
  • 举报
回复
前面兄弟给的代码可以完成将每六行生成一行数据并输出到文件中,但是我如果想控制每行输入固定字段,我该如何进行拆分呢?
例如源信息格式如下:
$WFE,1000.0440,W,09000.0000,Y,X,X,AA6 (a1~a8)
9980,0000043,0003440,040,040,040,002,023,030 (a9~a17)
8000,0054500,0005640,050,040,040,030,003,030 (a18~a126)
8596,0076700,0006340,300,450,023,230,300,030 (a27~a35)
5678,0004556,0045600,600,400,050,034,030,300 (a36~a44)
5665,4353000,0232434,340,034,045,320,030,200 (a45~a53)
以逗号分隔共53个字段,我只想输出a1,a9,a18(或者任意字段),如下:
$WFE,9980,8000
$WFE,9980,8020
$WFE,9980,8030
$WFE,9980,8060

我应该怎样提取他们??
野男孩 2010-05-04
  • 打赏
  • 举报
回复
帮顶。

简单处理的话,无非就是strtok拆分出来,用一个数组记住每个字段的开始地址即可。
chaoliu1024 2010-05-04
  • 打赏
  • 举报
回复
最近我也关心文件分割,顶一个!
suojunqi 2010-05-04
  • 打赏
  • 举报
回复
好像确实有点问题
lemontree197977 2010-05-04
  • 打赏
  • 举报
回复
好像strtok没有办法将获取的字符串分别存到a1~ a53,并写入文件啊??
赵4老师 2010-05-04
  • 打赏
  • 举报
回复
fgets
strtok
lemontree197977 2010-05-04
  • 打赏
  • 举报
回复
顶起来
田暗星 2010-04-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 jixingzhong 的回复:]
C/C++ code

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main(int argc, char* argv[])
{
ifstream ifile("1.txt");
string l……
[/Quote]
领分来了
yyg990441 2010-04-30
  • 打赏
  • 举报
回复
呵呵,我也写个玩玩.测试数据同3楼

#include<iostream>
#include<string>
#include<fstream>
using namespace std;
//自定义操纵器决定输出换行还是','
inline ostream& Append(ostream& strm){
static cnt=0;
return strm<<((++cnt%6)?',':'\n');
}
int main(){
ifstream in("a.txt");
ofstream out("b.txt");
string tmp;
while(getline(in,tmp)){
out<<tmp<<Append;
}
}
ithiker 2010-04-30
  • 打赏
  • 举报
回复
mark下,学习
only_delusion 2010-04-30
  • 打赏
  • 举报
回复
顶下 赚分
加载更多回复(7)

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧