Click here to Skip to main content
15,889,865 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi,
I have one C++ script that read one csv file, parse that and write in another csv file.
It works great when I try run that for one file. But when try read and write some files together it only do for first file.
C++
#include "StdAfx.h"
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <stdio.h>
#include <iostream>
#include <string>
#include <conio.h>

using namespace std;

typedef vector<string> stringArray;
typedef vector<char[40]> charArray;
stringArray listString; // store each line in the input file
vector<stringArray> data; // store data of the input file


/*
 * readInput is to read the input file name and get data in that file.
 */
void readInput(char *fileName){
  //  printf("****************ReadInput***************\n");
    // get input file name
   // printf("Input file name: ");
    int sum=0;
   // char fileName[256];
  //  cin.getline (fileName,256);

    // read file
    freopen(fileName, "r", stdin);
    string tmp = ""; // a line in the input file
    while(getline(cin, tmp)){

        // add string into vector
        listString.push_back(tmp);
       // cout << listString[listString.size() - 1] << endl;
        sum=sum+1;
        cout<<sum<<endl;
        if(sum>100000)break;
    }
    printf("\n\n");
}

/*
 * parseValues is to extract data in the input file
 */
void parseValues(){
    printf("****************ParseValue***************\n");
    for (int i = 0; i < listString.size(); ++i){
        char tmp[2048];
        strcpy(tmp, listString[i].c_str()); // copy string to char array
        stringArray tmpArray;
        // utilize string token to extract data
        char * pch;
        pch = strtok (tmp,",");
        while (pch != NULL){
            tmpArray.push_back(pch);
          printf ("%s\t",pch);
            // get the next token
            pch = strtok (NULL, ",");
        }
        data.push_back(tmpArray);
        printf("\n");
    }
}

/*
 * parseValues is to write data to the output.csv
 */
void writeOutput(){
    freopen("output1.csv", "w", stdout);

    //freopen("reza.txt", "w", stdout);
    // for each row

    for (int i = 0; i < listString.size(); ++i){
        // for each column

        for (int j = 0; j < data[i].size(); ++j)
        //if(atof(data[i][1].c_str())>1300)
        {

            cout << data[i][j].c_str() << ",";
        }

       cout << "\n";
        }

}

int main(){

    readInput("book2.csv");

    parseValues();
    writeOutput();
   
    readInput("1.csv");
    parseValues();
    writeOutput();

    return 0;
}


Please say how I can solve this and my code read second file too?
Regards,
Posted
Updated 10-Jan-12 11:36am
v2
Comments
Kethu Sasikanth 10-Jan-12 14:53pm    
1) in first readInput() you read data into "data" vector but it was not cleared for next use by readInput("1.csv")
2) close the file stream using fclose() before it is used again.
Try these two. All the best.
Rezame 10-Jan-12 15:10pm    
Hi,
clear my data vector.
data.clear();
But not work yet.
CPallini 10-Jan-12 15:29pm    
'C++ script' ?
:-D
Rezame 10-Jan-12 15:32pm    
yes,
c++
Andreas Gieriet 11-Jan-12 8:52am    
Why do you "abuse" stdin for that? Why freopen instead of fopen for the individual input files (not to talk about proper resource management: missing close of the reused stdin)?

Better use strtok_r, and you do not need to copy the string into a tmp array while parsing.

And finally, encapsulate into a class (avoid the global variables), so that you can instanciate it in main as many times you want.

Nit picking: C++ is not a "script" - say: use the proper terms...

Hi,

You need just to loop on a input files list.

C#
int main(){

    int x;
    string fileNameArray[3] = {"book1.csv", "book2.csv", "book3.csv"};
    
    for (x = 0; x < 3; x ++) {
       readInput(fileNameArray[i].c_str());

       parseValues();
       writeOutput();

    }   

    return 0;
}




Don't forget to change output file name each name, other wise it would be erased.


I see the problem, you need to close your file ate the end of the write out put functions :

/*
 * parseValues is to write data to the output.csv
 */
void writeOutput(){


    freopen("output1.csv", "w", stdout);
 
    //freopen("reza.txt", "w", stdout);
    // for each row
 
    for (int i = 0; i < listString.size(); ++i){
        // for each column
 
        for (int j = 0; j < data[i].size(); ++j)
        //if(atof(data[i][1].c_str())>1300)
        {
 
            cout << data[i][j].c_str() << ",";
        }
 
       cout << "\n";
        }

 fclose (stdout);
 
}


Best Regards.
EL GAABEB.
 
Share this answer
 
v3
Comments
Rezame 10-Jan-12 15:01pm    
Thanks.
Done.
But only read book1.csv and write for 3 csv one data that read from book1.
For book3 write correct data that read from book1.
Rezame 10-Jan-12 15:04pm    
Hi,
I close file too.
But only read book1.csv and writ same data for 3 output.
elgaabeb 10-Jan-12 16:11pm    
Have you ever changed the output file name for each intput file ?? ... try to debug step by step to see what's happening and what is wrong with your program.
Rezame 10-Jan-12 16:16pm    
Yes, changed

int x;
char* fileNameArray[3] = {"book2.csv", "1.csv", "book3.csv"};
char* file[3] = {"book11.csv", "book22.csv", "book33.csv"};

for (x = 0; x < 3; x ++) {
readInput(fileNameArray[x]);
parseValues();
writeOutput(file[x]);
}

After run this, I have 3 output with content "book2.csv" only.
It means it read only first csv nd write that in 3 output. I think must clear vctor after each read/write. I try that too and when try clear vector second and third output were zero. So my code cant read file 2 and file 3.
maybe problem is with freopen?
how I can write my code with fopen?
elgaabeb 11-Jan-12 7:46am    
you must write that inside writeOutput:

FILE * pFile;
pFile = fopen (file[x].c_str(),"w");
if (pFile!=NULL)
{

for (int i = 0; i < listString.size(); ++i){
// for each column

for (int j = 0; j < data[i].size(); ++j)
//if(atof(data[i][1].c_str())>1300)
{
fputs (data[i][1].c_str(),pFile);
}
}

fputs ("\n",pFile);
fclose (pFile);
}
Hi,

A Simple loop and clearing the buffers will do the trick.

Thanks,
 
Share this answer
 
Comments
Rezame 11-Jan-12 2:08am    
hi,
I done loop. try clearing buffers too but not works.
how must clear buffers?
Satheesh1546 11-Jan-12 4:20am    
change the function like this

void readInput(char *fileName){
// printf("****************ReadInput***************\n");
// get input file name
// printf("Input file name: ");
int sum=0;
// char fileName[256];
// cin.getline (fileName,256);

// read file
ifstream fin;
fin.open(fileName);
freopen(fileName, "r", stdin);
string tmp = ""; // a line in the input file
while(getline(fin, tmp)){

// add string into vector
listString.push_back(tmp);
// cout << listString[listString.size() - 1] << endl;
sum=sum+1;
cout<<sum<<endl;
if(sum>100000)break;
}
printf("\n\n");
}
Since you talk about C++, I think you should use C++ more effectively (see my comment to your question):

E.g.

Main function:

C++
int Main()
{
    CReadWriteCsv in1("In1.csv");
    in1.read(1000);
    CReadWriteCsv in2("In2.csv");
    in2.read(1000);

    in1.append("output.csv");
    in2.append("output.csv");

    return 0;
}


And the class to process CSV files:

C++
#ifndef CREARWRITECSV_H
#define CREARWRITECSV_H

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;

class CReadWriteCsv
{
public:
    CReadWriteCsv(char* infile): m_infile(infile) {}
    void read(int maxRecords)
    {
        ifstream is(m_infile);
        read(is, maxRecords);
    }
    void append(char* outfile)
    {
        ofstream os(outfile, ios_base::app);
        write(os);
    }

private:
    typedef vector<string> CRecord;
    typedef vector<CRecord> CContent;

    string m_infile;
    CContent m_content;

    void read(istream& is, int maxRecords)
    {
        m_content.clear();

        string line;
        while(maxRecords-- > 0 && getline(is, line))
        {
            CRecord record;
            m_content.push_back(readLine(line, record));
        }
    }
    void write(ostream& os)
    {
        for (CContent::iterator it=m_content.begin(); it!=m_content.end(); ++it)
        {
            writeRecord(*it, os);
        }
    }

    CRecord& readLine(const string& line, CRecord& record)
    {
        string field;
        istringstream iss(line, istringstream::in);
        while(getline(iss, field, ',')) record.push_back(field);
        return record;
    }

    void writeRecord(CRecord& record, ostream& os)
    {
        for(CRecord::iterator it=record.begin(); it!=record.end(); ++it)
        {
            if (it!=record.begin()) os << ",";
            os << *it;
        }
        os << "\n";
    }
};

#endif
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900