0

Please help me, I have been trying to do this for the past two-three hours, all with no luck. I have a number of strings comming in form input.txt in the format

string1 string2
string3 string4 
etc.

that I want to put into a std::set which is initially empty. I want to number the strings as they come in and put them into the set to keep track of the duplicates so I don't number them again. I am trying to initialize std::set<std::string> inGraph but can't make it work. I tried to initialize std::set<std::string> inGraph(0, tot_lines); where 0 to tot_lines is the range of the number of total strings I expect to get form the input. The I tried to initialize all with empty stirng like: std::set<std::string> inGraph(tot_lines, ""); and that failed. Here's what I have now:

struct StringInt {
    std::string name;  // associate name and number for each input string
    int number;
};

int main(int argc, char* argv[]) {
int tot_lines = 100;
int icv1, icv2;
std::string vert1, vert2;
std::set<std::string> inGraph();  // this is the set I want to initialize
std::set<std::string>::iterator sit;
std::vector<StringInt> stringInts(tot_lines*2);
StringInt* si;

std::ifstream myfile2 ("input.txt");
  if (myfile2.is_open()) {      
      while(myfile2 >> vert1 >> vert2) {
          // read in input, put it in vars below
          myfile2 >> vert1 >> vert2;  

if (inGraph.find(vert1) != inGraph.end()) {
      icv1 = i++;
      si->name = vert1;
      si->number = icv1;
      inGraph.insert(vert1);
      stringInts.push_back(*si);
  }
  else {
      icv1 = si->number;
  }
  if (inGraph.find(vert2) != inGraph.end()) {
      icv2 = i++;
      si->name = vert1;
      si->number = icv2;
      inGraph.insert(vert2);
      stringInts.push_back(*si);
  }
  else {
      icv2 = si->number;
  }
}

The error I get is: left of '.find' must have class/struct/union Can you please help me figure out how to initialize the std::set<std::string> inGraph so I can number the strings?

Napalidon
  • 135
  • 2
  • 11
  • You don't want a set of strings, since a set of strings provides no way to number the strings. Back up, describe exactly what you want to do, and get some suggestions for the right data structure to do it. – David Schwartz Sep 09 '13 at 01:35
  • Remove the `()` from the end of the declaration. You've declared a function. http://stackoverflow.com/questions/16680019/structure-expected-on-left-side-of-or-but-it-is-a-structure – Retired Ninja Sep 09 '13 at 01:36
  • @DavidSchwartz I am trying to number the strings in ascending order that are comming in from the file input.txt, I described it above, and I chose set since it is O(logn) instead of vector which is O(n) worst case. – Napalidon Sep 09 '13 at 01:38
  • BTW, you seem to have some of the same probems you had here: http://stackoverflow.com/questions/18689152/set-illegal-indirection-error#comment27531283_18689152 Specifically `si` points to nothing, and I'm pretty sure `std::vector stringInts(tot_lines*2);` doesn't do what you want. You probably want to use `stringInts.reserve(tot_lines*2);` instead. – Retired Ninja Sep 09 '13 at 01:41
  • @RetiredNinja yes, sorry for the duplicate post, but I have been struggling with this problem for awhile and I have no idea how to initialize si correctly. What does reserve do? – Napalidon Sep 09 '13 at 01:42
  • 1
    Well, I could ask what you think the argument to the vector constructor does. :) You're creating a vector that already has N default initialized StringInts in it where I think you were trying to give it a hint that it might need to grow to that size so it should allocate the memory up front. That's what reserve does, it makes the vector allocate enough memory to handle at least that many items but it is still empty. It just won't have to reallocate as you push things into it. – Retired Ninja Sep 09 '13 at 01:45
  • @RetiredNinja Ninja, someone told me to use "inGraph.find(vert1) != inGraph.end()" in the code above to check if string is already in the graph but when I look in the debugger it just skips the lines without setting anything, and I get an assertion error. I don't understand the syntax of the statement much what I had before was "(*(sit = alreadyCounted.find(str1)).compare(str1) != 0" which was also wrong. Do you have any idea how to check if number is already inGraph in the if statement? – Napalidon Sep 09 '13 at 02:43

1 Answers1

2

The error message is because you are a victim of Most Vexing Parse.

std::set<std::string> inGraph();

It is a function declaration whose return type is std::set<std::string>. Just remove the () after inGraph to make it a object declaration.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • Hi Mahesh, thanks for helping me again. And again you answer solved my problem :) But as usual I have another that came up it now says si is uninitialized, but I thought doing StringInt* si with a vector of StringInts is enough. How do I initialize si? – Napalidon Sep 09 '13 at 01:40
  • For your purposes, just remove the `*` from the declaration. There's no reason you need a pointer there. Once you've done so you'll need to change the `->` to `.` as well. – Retired Ninja Sep 09 '13 at 01:42
  • @RetiredNinja Oh I see, since I had a pointer and no 'new' object the compiler was complaining. Thanks Retired Ninja. – Napalidon Sep 09 '13 at 01:45
  • That solved both of my problems in the post, now I have other to deal with such as 'vector out of range Assertion failure' lol. But you guys help me a lot. Thanks ya'll. :) – Napalidon Sep 09 '13 at 01:48