Reputation: 2313
#include <iostream>
#include <fstream>
#include <cstring>
#include <map>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
//define a bool to determine if you're still in the file's header section or not
bool header = true;
//define the map as a multidimensional string array that stores up to 100 z-levels
//and 50x50 tiles per z level
char* worldmap[100][50][50];
int zLevel=0;
//header declaration map
map<string, char*> declarations;
//create an input file stream object
ifstream file;
//open file
file.open("map1.dmm");
//validate file
if(!file.good()){return 1;}
//begin reading the file
while(!file.eof()){
//create a character array to write to
char line[512];
//read the file line by line; write each line to the character array defined above
file.getline(line, 512);
//header check
if(header){
if(!line[0]){
header = false;
break;
}else{
bool declaringKey=true;
char* key={};
char* element={};
char* token[20]={};
token[0] = strtok(line, "\"()");
for(unsigned int n = 0;n<20;n++){
if(n>0)token[n] = strtok(NULL, "\"()");
//cout << token[0] << endl;
if(!token[n] || (token[n])[1] == '=')continue;
if(declaringKey){
key = token[n];
declaringKey=false;
}else{
//cout << "pow" <<endl;
element = token[n];
cout<<"declarations[" << key << "] = " << element << endl;
declarations.emplace(key,element); //<-------------- problem line, i think
cout << declarations[key] << endl;
}
}declaringKey=true;
}
}else{
if(!line[0]) {
zLevel++;
continue;
}
}
}
//string test = "aa";
return 0;
}
I'm trying to create a map loader that loads a simple map from a text file. I'm aware that there are other map loaders available but most of them do far more than I need them to. So far, this code only reads the header, which basically defines what each set of characters represents as a tile, for example: "aa" = "sand tile"
The problem is, when I'm emplacing the key/element into the declarations map, it seems to use the same element for all keys. I'm assuming that this is because by defining a character pointer it always points to the same data, and only serves the purpose of changing the value contained by that pointer, rather than allocating new data and keeping them separate.
But that raises another question, why does it emplace a different key with the same element, even though both are pointers..? Anyways,
How can I make it so that all keys/elements are independent character arrays, rather than pointers to the exact same space carved out by the array..?
EDIT: You can just assume the code works other than the fact that it stores the same element to all keys. Also, the element it stores is always the last one that's parsed out of the file's header section.
Upvotes: 0
Views: 308
Reputation: 153820
Just use a std::string
for the value, too. This should solve your immediate problem.
That said, do not use stream.eof()
to control a loop reading values! It does not work. Instead, always try to read from a stream and then verify if the read was successful, e.g.:
while (file.getline(line, sizeof(line))) {
// ...
}
Personally, I wouldn't read into a fixed size buffer and use a std::string
instead:
for (std::string line; std::getline(file, line); ) {
// ...
}
From this point I would also not use strtok()
but rather either the members of std::string
or suitable algorithms. This way I also wouldn't let astray, considering it a good idea to store pointers (not to mention that I can't deal with pointers and, thus, my programs don't use them).
Upvotes: 2