0

In my C++ program I have a text file that I read line by line into a vector called flights and afterwards I search for some strings inside this vector of strings, but unfortunately if I don't find any matches I get the following error

A flights vector has this format:

EMA CDG BritishAirways 120 100
CDG VIE AirFrance 120 100
EMA VIE BritishAirways 150 300
EMA CDG AirFance 130 80
GRO FFF Rayanair 130 80
FFF HHH AirItalia 100 50

Unhandled exception at at 0x769E4598 in OOP project.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0052F0F0.

I think I have found that the error must be somewhere in my connectedJourney functon:

/*  The following code searches for journeys that have a connection. so the use 2 different flights
First of all looks for flights that are leaving from the same airport that the user indicated and stores the flight details in "deptMatches". 
Secondly it will look for flights that have the destination that the user indicated and stores it in "destMatches". 
Thirdly it will check if the destination code of any of the deptMatches matches the departure code of any of the destMatches.*/
vector < vector < string >> connectedJourney(string airpCode1, string airpCode2, vector < string > flights) {
  vector < vector < string >> rawMatches;
  vector < string > deptMatches;
  for (unsigned int f1 = 0; f1 < flights.size(); f1++) {
    //store all the fligths that match the departure airport into deptMatches

    if (airpCode1 == flights[f1].substr(0, 3)) {

      deptMatches.push_back(flights[f1]);
    }
  }

  vector < string > destMatches;

  for (unsigned int f2 = 0; f2 < flights.size(); f2++) {
    //store all the fligths that match the departure airport into deptMatches

    if (airpCode2 == flights[f2].substr(4, 3)) { //the call stack says the error is at this line 

      destMatches.push_back(flights[f2]);
    }
  }

  if (deptMatches.size() == 0 || destMatches.size() == 0) {
    // check if there won't be any matches

    throw noEntryFound();

  } else {
    vector < string > cj_Matches; //connected journey matches
    for (unsigned int g1 = 0; g1 < deptMatches.size(); g1++) {

      for (unsigned int g2 = 0; g2 < destMatches.size(); g2++) {

        if (deptMatches[g1].substr(4, 3) == destMatches[g2].substr(0, 3)) {
          //if the arrival place of the first flight matches the departure place of the first flight then the details of both flights are saved into a vector within another
          rawMatches[0].push_back(deptMatches[g1]);
          rawMatches[1].push_back(deptMatches[g2]);
        }
      }
    }
    return rawMatches;
  }

}

I have also uploaded my whole project here if it is useful: https://drive.google.com/folderview?id=0B-VbnRtajCWIfmFxMk5UUncwSkNzNm8tT2xrU0hDM29kbzg4TUFKODJSUExMTV9oVDFncjA&usp=sharing

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Nimajik
  • 95
  • 1
  • 1
  • 10
  • I'd like to see a printed out `flights` vector. It looks like you're trying to get a substring from one of those strings, and you are simply trying to access out of bound positions in one or more of those strings. – AndyG Mar 24 '15 at 18:17
  • this is what a flights vector contains(one line one entry)(deptcode,arrivalcode, airway, time, price):EMA CDG BritishAirways 120 100 CDG VIE AirFrance 120 100 EMA VIE BritishAirways 150 300 EMA CDG AirFance 130 80 GRO FFF Rayanair 130 80 FFF HHH AirItalia 100 50 – Nimajik Mar 24 '15 at 18:19
  • Can you add it to the post? It's hard to tell where lines end in your comment. – AndyG Mar 24 '15 at 18:21
  • ok I added it to the post – Nimajik Mar 24 '15 at 18:25

2 Answers2

1

Try this:

  for (unsigned int f2 = 0; f2 < flights.size(); f2++) {
     //store all the fligths that match the departure airport into deptMatches
     string code = flights[f2];
     if (code.length() > 7 && airpCode2 == flights[f2].substr(4, 3)) { //the call stack says the error is at this line 

    destMatches.push_back(flights[f2]);
     }
  }

This is what I would have done:

   vector<string>::iterator iter = flights.begin(); 
   for (; iter!=flights.end(); ++iter) {
      istringstream is(*iter);
      string tokens[5];
      for (unsigned int i=0; i<5; ++i) {
     is >> tokens[i];
      }
      if (tokens[0] == airpCode1) {
     deptMatches.push_back(*iter);
      }
      if (tokens[1] == airpCode2) {
     destMatches.push_back(*iter);
      }
   }
Mustafa Ozturk
  • 812
  • 4
  • 19
0

You should look up "transitive closure" and Warshall's algorithm. I think my code below does what you're trying to do.

#include <string>
#include <iostream>
#include <set>
#include <vector>
#include <sstream>
#include <stdexcept>

// if you prefer to 'weight' your search on time
// uncomment time and comment price
#define PRICE
//#define TIME

using namespace std;

static const size_t NUMFLIGHTS=6;

static const char* data[] {
   "EMA CDG BritishAirways 120 100",
      "CDG VIE AirFrance 120 100",
      "EMA VIE BritishAirways 150 300",
      "EMA CDG AirFance 130 80",
      "GRO FFF Rayanair 130 80",
      "FFF HHH AirItalia 100 50"};

struct flight {
   void set(const string& input) {
      istringstream is(input);
      is >> dept >> dest >> airways >> time >> price;
   }
   string dept;
   string dest;
   string airways;
   unsigned int time;
   unsigned int price;
};

struct travelData {
   travelData() : weight(0), infinity(true) {}
   vector<flight> flights;
   unsigned int weight;
   bool infinity;
   void print() {
      auto i=flights.begin();
      for (;i!=flights.end(); ++i) {
     cout << i->dept << " " << i->dest << endl;
      }
      cout << weight << endl;
   }
};

struct database {
   vector< vector<travelData> > allflights;
   flight flights[NUMFLIGHTS];
   vector<string> locations;
};


travelData FlightExists(const flight* flights, const string& dept, const string& dest) {
   travelData ret;
   for (size_t i=0; i<NUMFLIGHTS; ++i) {
      if (flights[i].dest == dest && flights[i].dept == dept) {
     ret.flights.push_back(flights[i]);
#ifdef PRICE
     ret.weight = flights[i].price;
#elif LENGTH
     ret.weight = flights[i].time;
#else
     ret.weight = 1;
#endif
     ret.infinity= false;
     return ret;
      }
   }
   return ret;
}



database setup()
{
   database ret;
   set<string> locationsSet;
   for (size_t i=0; i<NUMFLIGHTS; ++i) {
      ret.flights[i].set(data[i]);
      locationsSet.insert(ret.flights[i].dept);
      locationsSet.insert(ret.flights[i].dest);
   }
   copy(locationsSet.begin(), locationsSet.end(), back_inserter(ret.locations));

   size_t len = ret.locations.size();
   for (size_t i=0; i<len; ++i) {
      string searchDept = ret.locations[i];
      vector<travelData> row;
      for (size_t j=0; j<len; ++j) {
     string searchDest = ret.locations[j];
     if (i == j) {
        travelData blank;
        blank.infinity = false;
        row.push_back(blank);
     } else {
        row.push_back(FlightExists(ret.flights, searchDept, searchDest));
     }
      }
      ret.allflights.push_back(row);
   }

   // Warshalls algorithn
   for (size_t k=0; k<len; ++k) {
      for (size_t i=0; i<len; ++i) {
     for (size_t j=0; j<len; ++j) {
        travelData& d = ret.allflights[i][j];
        travelData& s1 = ret.allflights[i][k];
        travelData& s2 = ret.allflights[k][j];

        if (!s1.infinity && !s2.infinity) {
           int sum = s1.weight + s2.weight;
           if (d.infinity) {
          d.infinity = false;
          d.flights.insert(d.flights.begin(), 
                   s1.flights.begin(), 
                   s1.flights.end());
          d.flights.insert(d.flights.begin(), 
                   s2.flights.begin(), 
                   s2.flights.end());

          d.weight = sum;
           } else if (d.weight > sum) {
          d.flights.clear();
          d.flights.insert(d.flights.begin(), 
                   s1.flights.begin(), 
                   s1.flights.end());
          d.flights.insert(d.flights.begin(), 
                   s2.flights.begin(), 
                   s2.flights.end());
          d.weight = sum;
           }
        }
     }
      }
   }


   return ret;


}

size_t GetIndex(const database& db, const string search) {
   size_t len = db.locations.size();
   for (size_t i=0; i<len; ++i) {
      if (db.locations[i] == search) {
     return i;
      }
   }

   throw runtime_error("bogus search");
}

travelData GetResults(const database& db, const string& dept, const string& dest) {
   travelData ret;
   size_t i_index = GetIndex(db, dept);
   size_t j_index = GetIndex(db, dest);
   return db.allflights[i_index][j_index];
}

int main() {
   database db = setup();

   travelData result = GetResults(db, "GRO", "HHH");
   result.print();

   return 0;
}
Mustafa Ozturk
  • 812
  • 4
  • 19