Reading text file with multiple data structures

Hello there ^^

I was wondering how I could read a text file with multiple data structures(not sure if it's called that way) into a matrix(typedef std::map<std::string, std::vector<std::string>> matrix) and header(typedef std::map<std::string, short> header) without creating additional ones.
Google didn't work any magic for me today. (Wasn't sure if I should post in beginners or here)

Part of the text file (they're really big):
ID	X	Y	TEXT
Cat	30	230	Chen
Fox	280	230	Ran
Youkai	280	70	Yukari

START	END	LABEL	CREATENEW
Cat	Fox	Affection	0
Cat	Youkai	Affection	0


I am able to read
ID	X	Y	TEXT
into a header for my matrix, but I don't want to read
START	END	LABEL	CREATENEW
into a new header/matrix, I keep that information in the same text file so I don't get swarmed with text files. (The structures are seperated by one empty line btw)

I was wondering if it's possible to put
ID	X	Y	TEXT	START	END	LABEL	CREATENEW
together after eachother in the same header making it possible to read the data underneath it.

I minimized the amount of code to demonstrate what I currently use
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 <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>

typedef std::vector<std::string> row;
typedef std::map<std::string, row> matrix;
typedef std::map<std::string, short> header;

using namespace std;
string f;

string getData(/*HWND hwnd, */header &index, matrix &data)
{
	/*while (f.empty()) f = DoFileOpen(hwnd);*/ //function to select a file
	
	f = "file.txt";
	ifstream file(f);

	if (file.is_open())
	{
		string line;
		bool ff = true;
		while (getline(file, line))
		{
			istringstream linestream(line);
			string label;
			getline(linestream, label, '\t');
			string field;
			short column = 0;
			while (getline(linestream, field, '\t'))
			{
				if(ff) {
					index[field] = column;
					column++;
				} else {
					data[label].push_back(field);
				}
			}
			ff = false;
		}
	}
	return f;
}


I can easily access the data I want with data["Cat"][index["TEXT"]]; to get "Chen". So I'm wondering if it's possible with the same matrix and header to do stuff like data["Cat"][index["LABEL"]] = "Affection" and if it's safe to use an iterator when there are two of the same START names.

~ Rii
Is 'ID' is a species type (if youkai can be considered a species...same idea though), and 'TEXT' is a name of a specific entity? So there might be multiple rows with ID = cat, each at a different location, with a different name? For the second table, I assume that represents the relationship between 2 species; if it says CAT YOUKAI AFFECTION, does that also mean YOUKAI CAT AFFECTION? What does 'CREATENEW' mean?
ID is a name that I read from another file which can't be edited, this value will never be the same with something else (there can't be two Youkai, this value is used to search, it can also be 445 instead of Cat, or anything else random)
TEXT is the name that will be displayed instead of ID. (Self created, There can be two Chen this way for example)
X and Y are coordinates

START is the first ID that will be used in a linkage between two IDs. (This is ordered)
END is the second ID that's used in the linkage.
LABEL is the sort of linkage the two have. (The link Cat has with Fox is Affection)
CREATENEW is something I put to 1 to draw a START that doesn't exist.

if it says CAT YOUKAI AFFECTION, does that also mean YOUKAI CAT AFFECTION?
No, it means only CAT -> YOUKAI AFFECTION. YOUKAI -> CAT could be YOUKAI -> CAT HATE or anything else.
Maybe a structure like this:

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
struct relationship
{
	relationship(){}
	relationship(string _disposition, bool _create_new) : disposition(_disposition), create_new(_create_new)
	{}

	// string ID; //optional, given the usage below
	string disposition;
	bool create_new;
};

struct animal_info
{
	animal_info(){}
	animal_info(string _ID, int _x, int _y, const string & _text) : ID(_ID), x(_x), y(_y), text(_text) {}

	relationship & operator[](string strID) { return relationships[strID]; }
	string ID;
	int x;
	int y;
	string text;
	map<string, relationship> relationships;	// usage: dispositions["Fox"] = relationship("Affection", 0); you could also make this map<animal_info *, relationship>
};

int main()
{	
	map<string, animal_info> Animals;
	Animals["Cat"] = animal_info("Cat", 30, 230, "Chen");
	Animals["Fox"] = animal_info("Fox", 30, 230, "Ran");
	// ...

	Animals["Cat"]["Fox"] = relationship("Affection", 0);
	Animals["Cat"]["Youkai"] = relationship("Affection", 0);
Thank you for your reply, I like this struct, I'll use it, thank you!
But I actually wanted to know what method I could use to read the file, I couldn't find anything regarding the file I have, I only know how to read the
ID	X	Y	TEXT
Cat	30	230	Chen
Fox	280	230	Ran
Youkai	280	70	Yukari
part, but I have no idea how to read the part underneath that in the same file, I don't want to make multiple files for these things.
The new data starts after an empty line
Last edited on
Oh...well that's easier :P

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

int section = 1;
while (getline(file, line))
{
    if (line == "")
    {
        section++;
        continue;
    }

    if (section == 1)
    {
        // process line as animal info
    }
    else if (section == 2)
    {
        // process line as relationship info
    }
}
Last edited on
Thank you so much! Perfect!
Sorry for the confusion at first, I thought it might be needed to explain the data, but I have something better now :D

Thank you once again!
*Sorry for barging in with a somewhat newbie question, I didn't get any replies in the beginner forums so I thought it was something advanced >.<"*
Topic archived. No new replies allowed.