2

Newb here... taking a C++ class on data structures. I am making a program that takes a list of chores from a text file and stores them in a dynamic array.

//In header/ In class:

private:
/* var to keep len of list */
int len = 99; // Not sure what to set this to or if I need to even set it.
/* add appropriate data structure to store list */
string *arr = new string[len];

//In .cpp:

ListOfChores::ListOfChores(string fileName) {
ifstream file(fileName, ifstream::in);
string line;
    if (file.is_open()) //Checking if the file can be opened
    {
        while (!file.eof()) // To get all the lines.
        {
            getline(file, line); // Gets a single line
            arr[len] = line; // Store a line in the array
            len++; // Increases the array size by one
        }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl; // Gives error if the file can't be opened
}

But I am getting an error for storing a line in the array. It says "Access violation reading location." There is another function executed in the main.cpp for printing the lines.

Rhuen
  • 23
  • 6
  • Off topic: `while (!file.eof()) // To get all the lines.` The comment lies. This will get all of the lines in the file plus one line that is not in the file. More on this bug here: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – user4581301 Sep 17 '16 at 21:22

1 Answers1

1

You overrun your array buffer at once because len is already 99. You should have a notion of capacity and length. Capacity is the maximum you can store without reallocating, and length is the actual number of data lines.

Please avoid this C-style array in C++ code. Use vector, which has been around for at least 20 years (STL) if I'm not mistaken.

(you're not a lost cause, you are already using std::string :))

Check this:

#include <vector>
//In header/ In class:

private:

/* add appropriate data structure to store list */
std::vector<string> arr;   // define a vector

//In .cpp:

ListOfChores::ListOfChores(string fileName) {
ifstream file(fileName, ifstream::in);
string line;
    if (file.is_open()) //Checking if the file can be opened
    {
       while (getline(file, line))
       {
           arr.push_back(line);
       }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl; // Gives error if the file can't be opened
}

Now arr.size() holds the number of lines, it is no longer limited to 99 lines but to the max. program memory capacity. You can still access line number 13 by arr[12] or arr.at(12) for boundary checked access.

proper way to iterate through it (C++11) for instance to print all lines:

for (auto s : arr)
{
   std::cout << s << std::endl;
}

Now, if you REALLY have to use an array, you can emulate/mimic what vector does (well, not as performant I'm sure, but does the job):

private:

 int len=0;
 int capacity=100;
 string *arr = new string[capacity];

now in the code, just before inserting (untested, but the idea is right):

if (len>=capacity)
{
   string *narr = new string[capacity+100];
   for (int i = 0; i < capacity; i++)
   {
        narr[i] = arr[i];
   }
   delete [] arr;
   arr = narr;
   capacity += 100; // growth
}

(you cannot use realloc or memcpy because you're handling objects in the arrays)

Jean-François Fabre
  • 126,787
  • 22
  • 103
  • 165
  • I would love to use this but the assignment requires us to use an array T_T – Rhuen Sep 17 '16 at 21:06
  • BTW it was worse than I thought. Check my edit (first lines). – Jean-François Fabre Sep 17 '16 at 21:10
  • Thanks so much. Yeah, I'm quite new to this -- my education in programming is minimal. Care to explain how I might emulate what vector does? – Rhuen Sep 17 '16 at 21:15
  • 1
    Could we get a correction on the `while (!file.eof())` that was copied from the question source? No point leaving a bug like that in the answer. – user4581301 Sep 17 '16 at 21:24
  • 1
    `while (getline(file, line)) {arr.push_back(line);}` will do everything that is needed thanks to [the magic of `operator bool`](http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool). – user4581301 Sep 17 '16 at 21:54
  • even better! edited (again). I'm a bit rusty when it comes to C++ file I/O. thx. – Jean-François Fabre Sep 18 '16 at 08:14
  • Now what would I do if we were required to use `unique_ptr`? – Rhuen Sep 30 '16 at 05:27
  • I think you can gather your now working source and ask a new (good) question about it. I'm not telling that to annoy you. I'm not able to answer on `unique_ptr`, but others will certainly. That's a completely different question. – Jean-François Fabre Sep 30 '16 at 08:38