Trying to create a list that contains multiple keys with multiple content for each key. Do not want to use multimap because it would double the size of the files and memory use (content without key is already 1 mg and growing). Trying to use this method that would increase size only by about 10%. If I could solve the first error, which i believe is usage of the iterator index, I think the rest would be okay.
The output file to be read/written is:
key0
content1
...
contentN
...
keyN
content1
...
content2
struct myStruct
{
string key;
list<string> content;
};
list<myStruct> MyList;
list<myStruct>::iterator i; // Also tried as list<string>
list<string>::iterator j, k, l;
string tkey, tcontent; // key and content to check for
// Test data
tkey = "a7b4";
tcontent = "this is a test";
// See if key exists
for (i = MyList.begin(); i != MyList.end(); i++)
{
j = find(MyList[i].key.begin(), MyList[i].key.end(), tkey); // ERROR 1
// If not, add key and content
if (j == -1) // ERROR 2
{
MyList[i].key.push_back(tkey); // ERROR 3
MyList[i].content[0].push_back(tcontent); // ERROR 3
}
// If yes, check if content exists
else
{
for (k = MyList[i].content.begin(); k != MyList[i].content.end(); k++)
// ERROR 3
{
l = find(MyList[i].content.begin(), MyList[i].content.end(),
tcontent); // ERROR 3
// If no, add content to key
if (1 == -1) // ERROR 2
{
MyList[i].content[k].push_back(tcontent); // ERROR 3
}
}
}
}
// Display to check accuracy of storage
for (i = MyList.begin(); i != MyList.end(); i++)
{
cout << MyList[i].key << endl; // ERROR 3
for (j = MyList[i].key.begin(); j != MyList[i].key.end; j++) // ERROR 3
cout << " " << MyList[j].content << endl; // ERROR 3
}
ERRORS:
1) error: no match for call to '(std::__cxx11::list<myStruct>) (std::__cxx11::list<myStruct>::iterator&)'
2) error: no match for 'operator==' (operand types are 'std::__cxx11::list<std::__cx11::basic_string<char> >::iterator {aka std::_List_iterator<std::__cxx11::basic_string<char> >}' and 'int')
3) error: no match for 'operator[]' (operand types are 'std::__cxx11::list<myStruct>' and 'std::__cx11::list<myStruct>::iterator {aka std::_List_iterator<myStruct>}')
struct myStruct
{
string key;
list<string> content;
};
list<myStruct> MyList;
list<myStruct>::iterator i; // Also tried as list<string>
list<string>::iterator j, k, l;
string tkey, tcontent; // key and content to check for
// Test data
tkey = "a7b4";
tcontent = "this is a test";
// See if key exists
for (i = MyList.begin(); i != MyList.end(); i++)
{
j = find(i->key.begin(), i->key.end(), tkey);
// If not, add key and content
if (j == i->key.end())
{
i->key = tkey;
i->content.push_back(tcontent);
}
// If yes, check if content exists
else
{
l = find(i->content.begin(), i->content.end(), tcontent);
// If no, add content to key
if (l == i->content.end())
{
i->content.push_back(tcontent);
}
}
}
// Display to check accuracy of storage
for (i = MyList.begin(); i != MyList.end(); i++)
{
cout << i->key << endl;
for (j = i->content.begin(); j != i->content.end(); j++)
cout << " " << *j << endl;
}
FYI, I have been away from programming for over 20 years and just now getting back into it helping others. Things have changed since Turbo C++ and Borland C++.
This is my first time using one of these sites as you can tell, since I was not able to get the code to appear in the box as yours did (I clicked the <> button that said code but did not seem to do anything).
I know using l can cause problems, but in the file it is an l. I must have keyed the 1 while I was transcribing it to this site. (I need to see if I can change the font in CodeBlocks so it will be more obvious if I happen to do this again).
Yesterday afternoon I had thought about the iterators and had tried using i., *i., (*i)., i->, *i->, (*i)-> and even using the & instead of *, but everything still came back with errors. I put it back to the way you suggested and the errors are stating "no match for operator=" (lines: 21, 44), "no match for operator==" (line: 23) and "no match for operator!=" (line: 44). There are a lot of "notes" but I figure those will disappear once the errors are fixed.
error: no match for 'operator=' (operand types are 'std::__cxx11::list<std::__cxx11::basic_string<char> >::iterator {aka std::_List_iterator<std::__cxx11::basic_string<char> >}' and '__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >')
I have searched the web and find mention of using/not using const with the iterator depending on the case; however, since I do not see const in the error message, I assume that is not the problem.
I found mention of using the auto for the iterators; so I replaced the list<myStruct>::iterator and list<string>::iterator with auto and these were the messages I received:
||=== Build: Debug in TestStructure (compiler: GNU GCC Compiler) ===
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\predefined_ops.h|194|error: no match for 'operator==' (operand types are 'char' and 'const std::__cxx11::basic_string<char>')
Ok. Tried this and got the same error message and 5 warning messages with 1 new one.
TestStructure.cpp|22|error: no matching function for call to 'myStruct::myStruct(std::__cxx11::string&, std::__cxx11::string&)'
which seems to me to indicate it is having a problem with the list<string> content assignment.
And wouldn't line 20 become if (i == MyList.end()) to indicate it reached the end and not found it?
Thanks
NOTE:
I tried changing line 5 to: myStruct(string k, string cnt) { key(k), content.push_back(cnt); }
The extra error above disappeared, but the 1 error and 5 warnings from before remained.
Changing "string to "const string &" worked. I really appreciate this. I hope this helps anyone else who may need to use a similar setup without resorting to multimap.