Tuesday, March 20, 2012

CSV or Txt file merger

After long time I am posting this article due to some busy works. Recently my friend has encountered a problem which was about file merging. If we have two or 3 files then we can simply merge in to one . For example , Lets assume in your directory you have 3 files (all are having extension .csv or .txt) , Simplest way to do this, 
 C:\<your file directory> copy *.csv targetfilename.csv  ( pretty simple right  ?) 
If you have more than 100 or 1000 files you can use above command to append or merge . Now my friend's requirement was can we merge files by column. Because above command only append next file in to end of previous file. 

I have written a C++ program to achieve this very fast column wise merging. Enjoy it . 
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <map>
#include <Windows.h>
using namespace std;


typedef map<int , char*> MAPFILES;

int main(int argc , char **argv)
{
cout <<"****************** CSV files merging program**************"<<endl;
cout <<"Written by vampire."<<endl;
cout<< "Date:20/3/2012"<<endl;
cout<<"Usage of this program..  program name  input.csv  output.csv "<<endl;
cout<<"***********************************************************"<<endl;
if(argc==1 || argc ==2)
{
cout <<"Wrong arg types. please contact vampire"<<endl;

}
else
{
ofstream myFile(argv[2], ios::out | ios::binary);
MAPFILES mapFile[40];
ifstream maininput;
int l_line=-1;
int l_realline =0;
int l_maxLine = 0;
maininput.open(argv[1]);

if(maininput.is_open())
{

while(maininput.good())
{
string line ;
char *zBuffer=new char[100];
memset(zBuffer,0, 100);
getline(maininput, line);
++l_realline;
int iFound =line.find_last_of("Timestamp");
if(iFound  != -1)
{
++l_line;
l_realline=0;
}

if(l_line ==-1)
cout <<"This is not a proper csv file. please contact to vampire"<<endl;
else
{
const  char *ptr = line.c_str();
int ip=0;
for(int i =0 ; i < line.size(); ++i)
{
if(i%2!=0)
{
zBuffer[ip] = ptr[i];
++ip;
}
}
mapFile[l_line].insert(make_pair<int,char *>(l_realline, zBuffer));
}
}
}
maininput.close();
cout <<"No of section found "<<l_line<<endl;
Sleep(10000);
/********************************************************************************/

int imin = 0;
for ( int i =0 ; i< l_line; ++i)
{
imin= mapFile[0].size();
if(imin > mapFile[l_line].size())
imin= mapFile[l_line].size();

}
map<int , char*>::iterator itr;
map<int , char*>::iterator itr1;

int iCount =0;
bool bfalse= false;

for(itr = mapFile[0].begin(); itr != mapFile[0].end(); ++itr)
{
if(iCount<imin)
{
char zBuff[1024];
memset(zBuff, 0, sizeof(zBuff));

char * ptr  =itr->second;
int iintiallength  =strlen(itr->second);
memcpy(zBuff,itr->second,iintiallength);

zBuff[iintiallength-1]=',';
zBuff[iintiallength]=0;

for(int j =1 ; j<=l_line; ++j)
{
itr1 = mapFile[j].find(iCount);
if(itr1 !=mapFile[j].end())
{
int iLen = strlen(mapFile[j].find(iCount)->second);
memcpy(zBuff+iintiallength,mapFile[j].find(iCount)->second,iLen);

iintiallength +=iLen;
zBuff[iintiallength-1]=',';
zBuff[iintiallength+iLen]=0;
bfalse =true;
}
else
{
bfalse = false;
}
}

if(bfalse)
myFile<<zBuff<<endl;
++iCount;
}
}

}
}

No comments:

Post a Comment