getting certain data from a text file

Started by
12 comments, last by Zahlman 19 years, 1 month ago
For that, you would probably want to go with dynamic memory allocation. In C, you use malloc for allocation, and realloc to re size the memory returned from malloc. I think the C++ way for dynamic memory allocation is using the 'new' keyword.

using malloc in C:

char * arr;
int amt_of_entries;

arr = (char*)malloc(amt_of_entries * sizeof(char));

and then you use realloc to change the size.
Advertisement
Quote:Original post by Lonefox1
i had a brain wave :P finally got it working after much frustration.. or atleast the reading it in part. just wanted to run it past you guys to see if im missing any huge mistakes which will bite me on the bum in the future

*** Source Snippet Removed ***

*** Source Snippet Removed ***

one thing i havnt figured out yet is how to change the array size depending on how many entrys are in the txt file, any suggestions for this would be great

cheers
lone


Since we are using C++, we are going to use the available facilities, and write stuff with proper C++ style. You actually already have a hint about "changing the array size" - look through your header includes, notice anything you're not actually using? That's right, "string" and "vector". We're going to fix that by using a std::string to represent the "name", and by reading into a std::vector of Monster's instead of an array of them:

Monster.h:
#ifndef MONSTER_H#define MONSTER_H#include <string>// Within the .h file, only #include the stuff that's needed for the .h file.// In our case, that's just the 'string'. It won't cause a problem, but it may// confuse you later to have extra stuff there.// It is usual C++ style to capitalize class names; I do the same with struct// names since in C++, structs and classes are really the same thing (there is// just a bit of syntactic sugar: structs expose data by default while classes// hide it).// It is bad form to actually instantiate anything in your header file, and we// can't use that syntax "struct Name { stuff } thing[10];" with a vector// anyway. (The reason it is bad form is that header guards won't protect you// from getting "multiple definition" errors when you do linking; read// http://www.gamedev.net/reference/articles/article1798.asp for details.)struct Monster {  std::string name; // now we make use of std::string  int health;  int strength;  int experience;  int gold;}; // no Monsters exist yet, we've just said what they look like.#endif


Monster.cpp:
#include <iostream>#include <fstream>#include <vector>#include "monster.h"// I'm not including string here because it's already provided by monster.h;// however, if we were actually to refer to the std::string type explicitly// here, I would include it - don't rely on one header to include another, but// don't include things when you don't need their definitions locally.using namespace std;int main() {  // Now we make use of the 'vector' container to hold our Monsters. For now  // you can just read the angle brackets as "of".  vector<Monster> monsters;  monster current; // a temporary Monster to read into.  ifstream data("iotest.txt");  if (!data.good()) {    // Failed to load file. We should exit the program in this case.    cerr << "couldnt find file\n";    exit(1);    // If this weren't in the main() function of the program, we might throw    // an exception or return an error code instead.             }  // For the entire length of the input file, read in a monster.  // The operator>> can be "chained" as shown: the operation returns the  // stream again. The stream can also be compared like a boolean to see if  // it's still possible to read. So this statement means "while (it is possible  // to) read in all these values into current,".  while (data >> current.name >> current.health >> current.strength >>                  current.experience >> current.gold) {    // And for as long as it is possible to read stuff into current, we should    // then copy the monster into the vector, like this:    monsters.push_back(current);  }  // Now we will output all the vector contents, in a way that should look  // familiar to you. (There are more advanced ways that let you write things  // more neatly and do some cool tricks, but I won't get into that now.)  for (int i = 0; i < monsters.length(); i++) {    // And now we do the same thing as we would have before: the vector    // overloads the operator[] so that it can behave like an array. The    // "length" method simply tells us how many things there are, so that we    // know how far to count up to with i.    cout << monsters.name << "\n";    cout << monsters.health << "\n";    cout << monsters.strength << "\n";    cout << monsters.experience << "\n";    cout << monsters.gold << "\n";  } }


Now, the next trick would be to make the Monster into a "real" object, giving it the ability to be read and written from a stream just like plain numbers or bits of text are (instead of having to read all its fields manually). But - another time :)
nice one Zahlman!! worked like a charm, noticed one thing tho:

"for (int i = 0; i < monsters.length(); i++)"

length() wasnt working for me so i used size(). that all helped alot thanks for that :)

lone
Oops, my mistake :) 'length' is provided as a synonym for 'size' in strings, but not in vectors.

This topic is closed to new replies.

Advertisement