c++ creating variables with dynamic names (or something)

Started by
10 comments, last by Zahlman 17 years, 4 months ago
Ive just started learning c++, and Ive come across something of a problem with something that I want to do. I need to create a variable of type int to store an ID number, and this is being read from a file. The thing is, I dont know how many IDs there are going to be in this file. I know how to use the eof() function in a while loop to read until the end of the file, but I need a new int to be made each time the loop runs, with a new name, e.g. int id_01, int id_02, int id_03 etc. onward until the file ends. Currently I dont know any way of creating a variable with a "dynamic" name. It would be good if i could have an "int count" variable that incremented at the end of each loop, then that value was somehow used as part of the "int id_n" name, but I dont know how you would do that. If anyone could help that would be great. Thanks Joe.
Advertisement
Why dont you just store them in a vector? Essentially you could just call the ID number by index number, starting at 0 of course.
Arrays and vectors can be used for just this type of thing. From your post I'm guessing you haven't yet covered those topics. A google search on the topics might be enlightening (though as a beginner the results can be intimidating). If you need more guidance than what search results will give you, just post.
The previous two posters are correct, but I think you might need more elaboration.

You might be thinking about how variables work in the wrong way. It took me a while to figure this out, but the right mindset really helps in problem solving. Variable names don't do anything by themselves; they're handles to a region of memory that you use while coding. The PC doesn't really need English-readable names, they're just for your benefit.

You need to think more like the PC. You need more regions of memory, not more variables. That's why you should learn more about pointers. One pointer is one variable name, but its value can be changed to refer to any block of memory.

So, create a single pointer, allocate an array of integers based on the count variable you mentioned, and change the pointer to refer to each int in that array, whenever you need to access it.
XBox 360 gamertag: templewulf feel free to add me!
Quote:Original post by templewulf
So, create a single pointer, allocate an array of integers based on the count variable you mentioned, and change the pointer to refer to each int in that array, whenever you need to access it.

Hmm, i wouldn't recommend you start dabbling with pointers if you've "just started learning C++". But templewulf is correct that you can think about variables as regions of memory.
I would recommend you go with an array and fill it with values, it would be an easy way to solve the problem you have in an easy way, and not necessary an ugly way either. =)

----------------------------------------------------------------------------------------------------------------------"Ask not what humanity can do for you, ask what you can do for humanity." - By: Richard D. Colbert Jr.
Quote:Original post by Donegrim
The thing is, I dont know how many IDs there are going to be in this file. ... It would be good if i could have an "int count" variable that incremented at the end of each loop, then that value was somehow used as part of the "int id_n" name, but I dont know how you would do that.


The easiest way would be to use a Vector. See these resources:
http://www.codersource.net/c++_vector_stl.html
http://www.cppreference.com/cppvector/index.html

Another way would be to create a dynamic array using the "new" keyword, then freeing the memory using the "delete" keyword. See this resource:
http://www.cplusplus.com/doc/tutorial/dynamic.html
[size="1"]Try GardenMind by Inspirado Games !
All feedback welcome.
[s]
[/s]

[size="1"]Twitter: [twitter]Owen_Inspirado[/twitter]
Facebook: Owen Wiggins

[size="1"]Google+: Owen Wiggins

Quote:Original post by Donegrim
Ive just started learning c++, and Ive come across something of a problem with something that I want to do. I need to create a variable of type int to store an ID number, and this is being read from a file. The thing is, I dont know how many IDs there are going to be in this file. I know how to use the eof() function in a while loop to read until the end of the file, but I need a new int to be made each time the loop runs, with a new name, e.g. int id_01, int id_02, int id_03 etc. onward until the file ends. Currently I dont know any way of creating a variable with a "dynamic" name. It would be good if i could have an "int count" variable that incremented at the end of each loop, then that value was somehow used as part of the "int id_n" name, but I dont know how you would do that. If anyone could help that would be great. Thanks
Joe.


Ok, what you are looking for is a container. A container is a type that allows you to store many objects of similar type and access them somehow.

Ill give you some example code, you may not understand it but it may help.

Lets assume that this file is a text file that has loads of id values in it ( and nothing else, yet [smile] ). Each number is seperated by newline or some whitespace.

The following code will read them all into a standard c++ type called std::vector. std::vector is a container that allows you to access elements with a number that represents the order in which the element was added, or the index of the value in the vector. std::vector needs to know the type of things you are storing inside it, so we add the type to the end of the name like so "std::vector<int>" for integers.

You can add a thing to a vector by calling the "push_back" member on it, like so:

myContainer.push_back( someValue ); // push a variable
myContainer.push_back( 10 ); // push a constant

You can access them like an array, with the square brackets []. Like an array, the first element is at location 0. The vector has a "size()" function which will tell you how many elements you can access.

// access first element
myContainer[0] = 21;

// look at size
cout << "We have a vector with " << myContainer.size() << " elements in it." << endl;

This is pretty much what you wanted, you wanted

id_1, id_2... id_n.

Instead, you take away 1 from the number and replace the underscore with square brackets around the number. if ourvector of ints is called "id":

id[0],id[1] ... id[n-1].

By saying "using namespace std;", which you may be familiar with, we can drop the "std::" prefix to simplify things.

Some code: (make sure the file ids.txt exists and has some numbers in it)
#include <vector>#include <iostream>#include <fstream>using namespace std;int main(){   ifstream fileIn( "ids.txt" );   vector<int> ids;   int input;   // this will handle both end of file and some kind of bad read   // like the next thing in the file isnt a number   while( fileIn >> input )   {       // add the id to our vector       ids.push_back(input);   }   // output them all to screen   cout << "Loaded " << ids.size() << " identifiers.\n";   for( int i = 0 ; i < ids.size() ; ++i )   {        cout << i << ") " << ids << endl;   }}


vectors are not the only type of container, but they are one of the easiest. containers allow you to do all sorts of other stuff, but that should suffice for the moment. Any questions just ask.
Thanks for your replies, Ill try out some ideas later. just wondering, would it be any different if I had created my own class, and I wanted to create instances of the class in such a way. I kow they are pretty much exactly the same thing, but Im just curious to see if there is any difference here.
Quote:Original post by Donegrim
Thanks for your replies, Ill try out some ideas later. just wondering, would it be any different if I had created my own class, and I wanted to create instances of the class in such a way. I kow they are pretty much exactly the same thing, but Im just curious to see if there is any difference here.


The beauty of std::vector is that it will work for all your user defined classes that are copy-constructible.

Copy constructible, this ones more tricky.You need a copy constructor (for class "Foo", a constructor with the signature "Foo( const Foo &foo )"). Again the compilers default will usually suffice. However, almost anything involving a pointer will break unless your copy constructor makes a copy of the pointed to object, or use some form of reference counting. Be warned.

Just slot in your class into the angle brackets and try it out. [smile]

std::vector<Foo> foos;

[Edited by - rip-off on December 6, 2006 4:37:33 PM]
Quote:Original post by rip-off
The beauty of std::vector is that it will work for all your user defined classes that are copy-constructible and default constructible.

It'll work for classes that aren't default constructible too.

Σnigma

This topic is closed to new replies.

Advertisement