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
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]