-2

I'm trying to read an inventory system into a struct array. When I call the function and it gets to the first line I try and write data into the array, I am given the error:

Unhandled exception at 0x777CA932 in Lab 09.exe: Microsoft C++ exception: std::out_of_range at memory location 0x00F3DC68.

Here's the struct:

struct inventory {

int record;
string toolname;
int quantity;
double cost;

};

Array declaration:

inventory unsortedArray[100];

Here's the function (assume first line of file is 83 #Electric Sander# 7 57.00):

void fillArray(inventory unsortedArray[]) {

ifstream file;
string line;
string delim = "#";
stringstream ss;
file.open("records.txt");
int i = 0;

while (!file.eof()) {

    getline(file, line);

    unsigned first = line.find_first_of(delim);
    unsigned last = line.find_last_of(delim);

    unsortedArray[i].toolname = line.substr(first, (last - first) + 1);

    line.erase(first, (last - first) + 1);

    ss << line;
    ss >> unsortedArray[i].record;
    ss >> unsortedArray[i].quantity;
    ss >> unsortedArray[i].cost;

    i++;
    }

    file.close();

}
Derek H
  • 31
  • 5

1 Answers1

1

Problem 1

Use of

while (!file.eof())

usually leads to problems. See Why is iostream::eof inside a loop condition considered wrong?

Problem 2

Use the correct type to capture the return values of std::string::find_first_of and std::string::find_last_of.

Use

auto first = line.find_first_of(delim);
auto last = line.find_last_of(delim);

or

std::string::size_type first = line.find_first_of(delim);
std::string::size_type last = line.find_last_of(delim);

Problem 3

Always check the return values of std::string::find_first_of and std::string::find_last_of before proceeding to use them.

auto first = line.find_first_of(delim);
auto last = line.find_last_of(delim);

if ( first == std::string::npos )
{
  // Didn't find it. Figure out what to do.
}

if ( last == std::string::npos )
{
  // Didn't find it. Figure out what to do.
}

// Both checks are done. Now you can use first and last.

My Suggestion

Use

while (getline(file, line)) {

   unsigned first = line.find_first_of(delim);
   unsigned last = line.find_last_of(delim);

   if ( first == std::string::npos )
   {
      break;
   }

   if ( last == std::string::npos )
   {
      break;
   }

   unsortedArray[i].toolname = line.substr(first, (last - first) + 1);

   line.erase(first, (last - first) + 1);

   // Don't use ss << line
   // Construct ss in the loop. You don't need to mess with its
   // old state

   std::istringsteram ss(line);
   ss >> unsortedArray[i].record;
   ss >> unsortedArray[i].quantity;
   ss >> unsortedArray[i].cost;

   i++;
}
Community
  • 1
  • 1
R Sahu
  • 196,807
  • 13
  • 136
  • 247