Need help with dynamic array of objects with user defined functions.

Suppose how had a text file that looks like this,

Lemon 1

Apple 2

Orange 3

How would you create a user defined function to generate a dynamic array of objects based on amount of records in the text file, without applying a set number for the array. So basically reading each line and seeing how much orders there are without including the blank lines.

1
2
3
4
5
6
7
8
//I thought that this would work but for this program my professor doesn't want user input.
Fruit *myfruit = new Fruit[size];
int input;
for(int i=0; i<size; i++){
cin >> input;
myfruit[i[.setFruit(input);
}
return myfruit;
Last edited on
Use a
vector<Fruit>
then you can add to it whever you feel peckish.
I would but my professor doesn't want us to use vectors. :(
Last edited on
If you can't extend your arrays dynamically, then you could always read the file TWICE: the first time just to count the number of items, the second time (after creating a dynamic array of the counted size) to actually read the items.
Typically, you want objects to serialize and deserialize themselves using standard io streams.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Fruit {
    std::string name;
    int id;

public:
    Fruit() : id(0) {}
    Fruit(std::istream& is) {
        std::string line;
        std::getline(is, line);

        std::istringsteam iss(line);
        iss >> name >> id;

        std::getline(is, line);
    }
};


Instead of using raw memory directly, use a standard container. Not sure what to use? std::vector is usually a reasonable default.

Finally, you could use a Creator/Factory to do the actual load.
1
2
3
4
5
6
7
8
9
std::vector<Fruit> factory(std::string filename) {
    std::vector<Fruit> fruits;

    std::ifstream is(filename);
    while (is)
        fruits.push_back(Fruit(is));

    return fruits;
}


Finally, you use the factory.
1
2
3
4
5
typedef std::vector<Fruit> Fruits;

int main(int argc, char* argv[]) {
    Fruits fruits = factory(argv[1]);
}
Last edited on
You could read the first line, create an array of size one, populate the first element.

Try to read the next line; if it doesn't exist, done.

If it does exist, create an array of size (size of the current array, plus one), copy everything from the current array into the new array, delete the current array, and then populate the newly created last element of the array. Now go back to "Try to read the next line..." above.


Alternatively, you could read all the lines first, counting how many there are. Make an array that size. Then read all the lines again, but this time each time you read a line, populate an element of the array.

I would but my professor doesn't want us to use vectors. :(

I am so sick of teachers of C++ starting with the more advanced use of raw arrays and manual memory management. Teach beginners beginner level C++. it's so ******* obvious; what is wrong with these people?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <string>
#include <fstream>
using namespace std;


struct Fruit
{
   string name;
   int id;
};


istream &operator >>( istream &strm, Fruit &F ) { return strm >> F.name >> F.id; }
ostream &operator <<( ostream &strm, const Fruit &F ) { return strm << F.name << " " << F.id; }


Fruit * readFruits( string filename, int &num )
{
   // Count the fruit
   Fruit F;
   num = 0;
   ifstream in( filename );
   while ( in >> F ) num++ ;
   in.close();

   // Now re-read and store them
   Fruit * store = new Fruit[num];
   in.open( filename );
   for ( int i = 0; i < num; i++ ) in >> store[i];
   in.close();

   return store;
}


int main()
{
   int numFruit;
   Fruit *store = readFruits( "fruit.txt", numFruit );

   cout << "You read the following:\n";
   for ( int i = 0; i < numFruit; i++ ) cout << store[i] << '\n';

   delete [] store;
}


You read the following:
Lemon 1
Apple 2
Orange 3
closed account (1vRz3TCk)
Repeater wrote:
I am so sick of teachers of C++ starting with the more advanced use of raw arrays and manual memory management. Teach beginners beginner level C++. it's so ******* obvious; what is wrong with these people?

I personally see it as fundamentals rather than advanced...but then again I'm the sort of person that learns best from the bottom up rather than top down.
Not all programming languages have the equivalent of std::vector, so it depends whether you are teaching c++ or teaching more generic computer programming.

C++'s vectors are fantastic for desktop-type programs because of their flexibility and the way that compilers have been optimised to use them. But they are a nightmare for parallel computing with MPI, where I would revert to standard or dynamically-allocated arrays to distribute known amounts of memory to multiple processors.

I think that you probably have to learn all three:
- fixed-size arrays;
- dynamically-allocated (new and delete) arrays;
- vectors (and other container classes).

If you are a scientist you probably ought to look at std::valarray as well.
"Fundamental" is not the same as "for beginners". The whole point of higher level programming languages is so that we don't need to worry about the fundamentals so much.

I'm the sort of person that learns best from the bottom up rather than top down.


In C++, the basic, beginning, simple, bottom level object for holding a collection of objects of the same type is a vector. That's the bottom. Manual memory management is fundamental, but so is assembly; we don't teach that to beginners of C++ until they've learned the basics, and many C++ programmers never learn fundamental assembly. Vector is more basic in C++ programming than arrays and manual memory management. Vector is for beginners, and advanced programmers too. Vector does what beginners want, and what beginners need, and is easily understood, and allows beginners to get on with programming and learning.

If the goal is to teach people how to program effectively in C++, the teaching of arrays and manual memory management before teaching actual C++ is a mistake, pure and simple. I suspect that the teachers doing this are either teaching C with Classes, or they've never programmed professionally and think they're teaching some kind of philosophical practical history class.
Last edited on
Thanks guys for the help. What I was wondering @lastchance is what do you mean by file name? Is that for the string name in the struct or the actual text file.
Usually I do this,

1
2
ifstream inputFile;
inputFile.open("Fruit.txt");
Last edited on
closed account (1vRz3TCk)
Repeater wrote:
Did you start with assembly?

If I remember correctly, it was 68K assembly, C/C++, Modula-2, and Pascal depending on what concept was being taught.
Awsom3Alan3 wrote:
What I was wondering @lastchance is what do you mean by file name?
filename is just one of the function's arguments - it allows you to send whatever name of file you choose rather than being hardcoded to "fruit.txt". Just adds more flexibility, that's all, since I didn't know what your actual input file was called.

1
2
ifstream inputFile;
inputFile.open("Fruit.txt");

and
ifstream inputFile("Fruit.txt");
As far as I'm aware the second version does the same as the first, in one less line of code. There's usually many different ways of doing things. (Like learning about arrays in C++ !!)
Last edited on
If I remember correctly, it was 68K assembly, C/C++, Modula-2, and Pascal depending on what concept was being taught.


Was assembly used when the concept being taught was "how to program effectively in C++"?
closed account (1vRz3TCk)
Repeater wrote:
Was assembly used when the concept being taught was "how to program effectively in C++"?

No, that was to do with computer architecture but it did make pointer, arrays, references, and memory management a piece of cake.

The point is different people learn in different ways, there is no right or wrong way. Teaching is the same, no right or wrong way...maybe less appropriate depending on aims of the course.
Topic archived. No new replies allowed.