Need a recommendation on how to proceed with this task...I am starting new in C++ (after taking it in high school 11 years ago it has been forgotten and has changed alot). I have put the code I have below and some sample lines of data...any recommendations on how to load my array of weather observations would be appreciated. You will find that data is separated by a space and line breaks between observations. I only need the first several lines to remain individual and the rest of the observation I want to store as a string 'otherstuff'...is this even possible to do? I was having trouble with the getline working (which I know from reading is a common mistake). Help would be appreciated...

Attached below 1) Code to present 2) Sample Text

#include <iostream> 
#include <fstream>
#include <string>
#include<iomanip> 
using namespace std; // put standard names into default namespace

//Struct Weather to decode obs in txt file to individual components
struct Weather {
    int years;
    int months;
    int days;
    int hours;
    int windr;
    int windsp;
    int gust;
    int waveht;
    int waveperiod;
    string otherstuff();
};


void main() {

string stuff;
int counter = 0;
Weather Later[75000]; 

/*I have 75000 weather observations to decode and I want the structure to easily check each parameter against limitations I have using If-Then nested in a For-Loop (or While)*/

ifstream DataFile("2007.txt");
while(!DataFile.eof())	{
    getline(DataFile, stuff, ' ');
// This is where I want to distribute the paramters to the struct
    counter++;
    cin.get();
} 
DataFile.close();
/*This is where I want the nested If in a For loop to check the array of Structs once I dl all data*/
}

/****DATA FILE VIEWS LIKE THIS***

YYYY MM DD hh WD   WSPD GST  WVHT  DPD   APD  MWD  BAR    ATMP  WTMP  DEWP  VIS
1999 01 27 00 235  5.7  6.6   .47  9.09  3.89 131 9999.0   4.3   7.0   -.8 99.0
1999 01 27 01 999 99.0 99.0 99.00 99.00 99.00 999 9999.0 999.0 999.0 999.0 99.0
1999 01 27 02 249  5.7 99.0   .58  3.45  3.87 261 9999.0   5.2 999.0   -.8 99.0
1999 01 27 03 253  6.2  7.1   .59  3.45  3.72 253 9999.0   5.5   7.0   -.6 99.0
1999 01 27 04 999 99.0 99.0 99.00 99.00 99.00 999 9999.0 999.0 999.0 999.0 99.0
1999 01 27 05 254  7.8  9.0 99.00 99.00 99.00 999 9999.0 999.0   7.0 999.0 99.0
1999 01 27 06 999 99.0 99.0 99.00 99.00 99.00 999 9999.0 999.0 999.0 999.0 99.0
1999 01 27 07 999 99.0 99.0   .81  4.35  3.95 214 9999.0   4.7 999.0    .5 99.0
1999 01 27 08 999 99.0 99.0   .78  4.55  4.00 215 9999.0 999.0   7.0 999.0 99.0
1999 01 27 09 263  4.3  5.8   .71  4.17  4.08 217 9999.0   4.7   7.0 999.0 99.0
1999 01 27 10 999 99.0 99.0 99.00 99.00 99.00 999 9999.0   4.5   7.0    .4 99.0
1999 01 27 11 999 99.0 99.0 99.00 99.00 99.00 999 9999.0 999.0 999.0 999.0 99.0
1999 01 27 12 999 99.0 99.0 99.00 99.00 99.00 999 9999.0 999.0 999.0 999.0 99.0
1999 01 27 13 999 99.0 99.0 99.00 99.00 99.00 999 9999.0 999.0 999.0 999.0 99.0
1999 01 27 14 282  4.0  5.1   .58  4.76  4.19 199 9999.0   4.4   7.0  -1.3 99.0
*/

are you programming on a VAX/VMS!? lol

your [programming] life would be a lot easier (at least for this task) if you did this in C#. Check it out - if you're familiar with C++ you should transition very well. The reason for the suggestion is that a lot of the libraries available will handle the majority if this for you and much more user friendly than that of C++ (STL).

Sadly I have only C++ available to me...After using other languages, I'm mad about how difficult file i-o is with C++, but I don't remember it being too difficult...any help would be appreciated...

> Sadly I have only C++ available to me
cheer up, i/o is much (much) easier in C++ than in C#.
something like this should get all the data in.

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

struct Weather
{
    int years;
    int months;
    int days;
    int hours;
    int windr;
    double windsp;
    double gust;
    double waveht;
    double waveperiod;
    string otherstuff; // rest of line?
};


int main()
{

  string stuff;
  vector<Weather> Later ;

  ifstream DataFile("2007.txt");
  while( getline( DataFile, stuff ) )
  {
      istringstream stm(stuff) ;
      Weather w ;
      stm >> w.years >> w.months >> w.days >> w.windr
          >> w.windsp >> w.gust >> w.waveht >> w.waveperiod ;
      w.otherstuff = stuff.substr( stm.tellg() ) ;
      Later.push_back(w) ;
  }
  // no of lines read is Later.size()
  // Weather structures are stored in Later[0], Later[1] etc.
}

some of the variables in your struct must be double instead of int . they are real numbers in the file.
also prefer using a vector to an array. that way, you are not limited by hard-coded limits like 75000 .the vector resizes itself as required.

Thanks for the help. So many tools I didn't know existed...out of curiosity what is the istringstream? Thanks for recommending vector...I will like using that way more than the old school hard numbered array...

A semi official definition of istringstream:

istringstream provides an interface to manipulate strings as input streams.

The objects of this class maintain internally a pointer to a stringbuf object that can be obtained/modified by calling member rdbuf. This streambuf-derived object controls a sequence of characters (string) that can be obtained/modified by calling member str.

> Sadly I have only C++ available to me
cheer up, i/o is much (much) easier in C++ than in C#.
something like this should get all the data in.

string stuff;
  vector<Weather> Later ;

  ifstream DataFile("2007.txt");
  while( getline( DataFile, stuff ) )
  {
      istringstream stm(stuff) ;
      Weather w ;
      stm >> w.years >> w.months >> w.days >> w.windr
          >> w.windsp >> w.gust >> w.waveht >> w.waveperiod ;
      w.otherstuff = stuff.substr( stm.tellg() ) ;
      Later.push_back(w) ;
  }
}

lol. hardly much easier. But, i agree that it's not rocket science... Keep in mind, easy is a relative term and to someone who hasn't coded in C++ in over ten years the code above may not be as easy to them read/use. I like C++ and what not, but why use it when there is managed code with much more elegant libraries for trivial tasks such as file i/o.

Help? Can't get this substr to work...

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

struct Weather
{
    int years;
    int months;
    int days;
    int hours;
    int windr;
    double windsp;
    double gust;
    double waveht;
    double waveperiod;
    string otherstuff; 
};


int main()
{
  int a =0, i=0,j=0;
  string DataStream1;
  string DataStream2;
  string DataStream3;
  vector<Weather> Earlier;
  vector<Weather> Later;
  vector <Weather> Search;

  cout<<"Pulling in data...Please wait...."<<endl;
  ifstream DataFile1("Earlier.txt");
  while(getline(DataFile1, DataStream1))
  {
      cout<<"ok"<<endl;
	  istringstream Incoming(DataStream1);
      Weather w;
      Incoming >> w.years >> w.months >> w.days >> w.hours >> w.windr >> w.windsp >> w.gust >> w.waveht >> w.waveperiod;
//HERE IS THE ERROR BELOW...	  
w.otherstuff = DataStream1.substr(Incoming.tellg());
//****************/
      Earlier.push_back(w);
return 0;
}	  
  }
//HERE IS THE ERROR BELOW...	  
w.otherstuff = DataStream1.substr(Incoming.tellg());
//****************/

is it a compiler error? if yes, what is the error diagnostic (message)? and which compiler are you using?

if no, what is the error? what do you expect will happen? and what is actually happening?

It is not a compiler error. It is a "Unhandled exception in my.exe (Kernel32.dll): 0xE06D7363: Microsoft C++ Exception...I am using Microsoft VC++ 6.0...Thanks.

What I want to happen is that the data stream coming in is broken into the components on the first line of "Incoming". Then I want the rest of the stream from that line of data to be placed into the component "otherstuff"...The "otherstuff" part of the struct is what's giving me the exception...

Figured out part of the problem...the program didn't like my data file header, so I deleted it...I used the call stack to figure that out...By the way, anyone that doesn't know about the Call Stack (Alt-7), it is a great tool to help you figure out what you missed in the debug!

> the program didn't like my data file header, so I deleted it.

int main()
{
  int a =0, i=0,j=0;
  string DataStream1;
  string DataStream2;
  string DataStream3;
  vector<Weather> Earlier;
  vector<Weather> Later;
  vector <Weather> Search;

  cout<<"Pulling in data...Please wait...."<<endl;
  ifstream DataFile1("Earlier.txt");
  while(getline(DataFile1, DataStream1))
  {
    cout<<"ok"<<endl;
    istringstream Incoming(DataStream1);
    Weather w;
    Incoming >> w.years >> w.months >> w.days 
             >> w.hours >> w.windr >> w.windsp 
             >> w.gust >> w.waveht >> w.waveperiod;

    // this would be a little more robust;
    // skip the badly formatted lines in the file.
    // you might want to print out a diagnostic here
    if( !Incoming ) continue ; // skip the current line

    w.otherstuff = DataStream1.substr(Incoming.tellg());
    Earlier.push_back(w);

    // remove the return. you need the loop to execute for each 
    // line in the file; not quit after the first line is read 
    // return 0; 
  }	  
}

> .I am using Microsoft VC++ 6.0
consider switching to a modern compiler.
you can download VC++ 9.0 from http://www.microsoft.com/express/download/

What I ended up doing was modifying the data and eliminating the need for the "otherstuff" string. It was causing a headache. Would still be interested in knowing why that was causing so much trouble...

Thanks for the recommendations vijayan...I did move the return 0 in my code, just not on the post. Thanks for the other recommendations, seemed alot more robust as mentioned. I will give that a try.

> Would still be interested in knowing why that was causing so much trouble...
the c++ standard requires that before any input operation on a streambuf is performed, a sentry object must be constructed. sentry defines a class that is responsible for doing exception safe prefix and suffix operations on a streambuf. it is a (commonly found) technical error to access the streambuf for extraction operations without a sentry being constructed first.
vc++ 6.0 pre-dates the c++ standard. my guess is that it is trying to access the streambuf without a sentry; in case the state is not good, tellg returns an incorrect result (there is no sentry to catch the error). and the string::subst throws std::out_of_range.
either skipping over the erraneous line or using a modern (conforming) compiler would make this particular error go away.

This article has been dead for over six months. Start a new discussion instead.