[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [OT] C++ programming: keeping count of data items read from file



James Allsopp wrote:
hi,
Try something like this, just add some pointers;
scan is just a simple object and l is a class vector.
HTH
jim

int nearest::readdata(std::string s, std::vector<scan> & l)
{
   //read in scuba core list
     std::ifstream input(s.c_str());
     std::string temp, pos, x ,y;
     char * t;
     std::cout <<"Reading " << s <<std::endl;
    while(!getline(input,temp).eof())
   {
       scan n;
         std::stringstream s(temp);
       s >> n.name;
       s >> x;
       s >> y;
       n.glon=strtod(x.c_str(),&t);
       n.glat=strtod(y.c_str(),&t);
         l.push_back(n);
   }
   input.close();
   return 0;
}


Thanks for your pointer. For future references, here is what I have working so far:
///////////////////////////////////////////////////////

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


/* read 2D data from a file which has each a data vector on each line. The function allocates memory at the pointer supplied and returns 0 if the reading went well. Partial reading of the data (first few numbers in each line and first few lines in the file) is also supported.

post: Dynamic memory has been allocated and needs to be cleared when not needed. return: Retuns 0 if files is successfully read otherwise a non-zero is returned.
 */
int iReadDataFromFile(std::string strFN,//file which holds the data
		      double **dppData,//address of pointer to save data in
		      int iR,//read these many top dimensions
		      int iC /*read these many top data lines*/
    )
{
    int r,c;
    int iCtr=0;
    double x;

    iCtr = 0;//keep count of items read
    int iLN=0;//initialize the line number counter
    std::string str;

    //open the  file to read in the data
    std::ifstream isData(strFN.c_str(),std::ios::in);
    if (!isData) {
	std::cerr << "ERR: opening file " << strFN << std::endl;
	return -2;
    }

std::clog << "Reading 2D data from file '" << strFN << "'." << std::endl;

    *dppData = new double [iR * iC];//allocat memory
double *dpData= *dppData;//make a local variable (synonym); easier to use

#ifdef VERBOSE_READ_DATA_FILE
    std::clog << "Data read: " << std::endl;
    std::clog << std::setprecision(5);
    std::clog << std::setiosflags(std::ios::scientific);
#endif

    //now do the reading
    for (c = 0; c < iC; c++,iLN++) {//for first iC lines in the file
	if ( ! (std::getline(isData, str)) ) {//if line reading went bad
	    std::cerr << "ERROR: Insufficient data lines in " << strFN
		      << ". Expected " << iC << " lines but got only "
		      << iLN+1 << std::endl;
	    isData.close();//don't need this anymore
	    return -1;
	}
	else {//line was read okay
	    std::stringstream ss(str);
	    for (r = 0; r < iR; r++){//for first iR nums in line
		if ( !(ss >> x)){//reading the stream failed
		    std::cerr << std::endl <<
			"ERROR while reading item  " << r+1 <<
			" on line  " << iLN + 1 <<
			" in file " << strFN << std::endl;
		    isData.close();//don't need this anymore
		    return -1;
		}
		else {//reading the stream went okay
		    dpData[c + r*iC]  = x;//choose col- or row-major here
		    iCtr++;
#ifdef VERBOSE_READ_DATA_FILE
		    std::clog << dpData[c + r*iC] << " ";
#endif
		}
	    }//end for first iR nums in line
#ifdef VERBOSE_READ_DATA_FILE
		std::clog << std::endl;
#endif
	}//end else line was read okay
    }//end for first iC lines in the file

#ifdef VERBOSE_READ_DATA_FILE
    std::clog << std::resetiosflags(std::ios::scientific);
    std::clog << std::setprecision(0);
#endif

    isData.close();//don't need this anymore
    return 0;
}




int main(int argc, char * argv[]) {


    std::string strFileName("data.dat");

    double *dpData=NULL;

    iReadDataFromFile("data.dat",&dpData,3,9);
    delete [] dpData;

    return 0;
}


///////////////////////////////////////////////////////


I compiled it using either of the following to command depending on if I wanted to see what was being read:
$> g++ -g -DVERBOSE_READ_DATA_FILE -ansi -Wall readdata.cc -o readdata
$> g++ -g  -ansi -Wall readdata.cc -o readdata


I am sure the above routine can be further improved. One way to make it more C++-like is to use exceptions to see if something went wrong with getline or while reading a number from the string stream.

regards,
->HS



Reply to: