0

I am trying to split data from a file using delimiters BUT after that I would like to split certain strings AGAIN using white spaces but I keep running into a compiler error. the section of code is as follows...

PS: I have not shared all the code so if it seems incomplete that is why, I am just looking for a way to re-split the selected strings.

bool loadProperties(char* residential, char* commercial,
                    PropertyContainer* thePropertyContainer) {

   ifstream propertyFile;
   int datapos = 6;
   Property* propertyType = NULL;

   propertyFile.open(residential, ios::in);

   if (!propertyFile.is_open()) {
      cout << "Cant open file: " << residential << endl;
      return false;
   }

   while (propertyFile.good()) {

      getline(propertyFile, buffer);

      typedef tokenizer<char_separator<char> > tokenizer;
      char_separator<char> sep("\n\t\0,*");
      tokenizer tokens(buffer, sep);

      for (tokenizer::iterator pos = tokens.begin();
            pos != tokens.end(); ++pos) {

         if (!validate(datapos, *pos)) {
            return false;
         }

         switch(datapos) {
         case 6:
            vector < string > splitstring; <------------------------ (LINE 127)
            boost::split(splitstring, *pos, boost::is_any_of(" ")); <------this is where I am trying to split via white space for a second time.

            if (splitstring[0] == "RS") {
               propertyType = new ResSales;
            } else if (splitstring[0] == "RS") {
               propertyType = new ResRentals;
            } else {
               return false;
            }

            break;
         case 7:
            propertyType->setOwner(*pos);
            break;
         case 8:
            propertyType->setAddress(*pos);
            break;
         case 9:
            propertyType->setSuburb(*pos);
            break;
         case 10:
            propertyType->setPostcode(changeString<int>(*pos));
            break;
         case 11:
            dynamic_cast<Residential*>(propertyType)->setBedrooms
                        (changeString<int>(*pos));
            break;
         case 12:
            if (propertyType->getType() == "ResSales") {
               dynamic_cast<Sales*>(propertyType)->setAuctionDate(*pos);

            } else if (propertyType->getType() == "ResRentals") {
               dynamic_cast<Rentals*>(propertyType)->setBond
               (changeString<double>(*pos));
            }
            break;
         case 13:
            if (propertyType->getType() == "ResSales") {
               dynamic_cast<Sales*>(propertyType)->setPrice
               (changeString<double>(*pos));

            } else if (propertyType->getType() == "ResRentals") {
               dynamic_cast<Rentals*>(propertyType)->setMonthlyRent
               (changeString<double>(*pos));
            }
            break;
         }

         if (datapos >= 14) {
            thePropertyContainer->addProperty(propertyType);
            datapos = 6;
         } else {
            ++datapos;
         }
      }




   }

   propertyFile.close();
   return true;
}

basically if case is 6, I want to white space split the token again, Am at a loss as how to achieve this, I am trying to use boost as you can tell. but I get the error....

any help is greatly appreciated, thanks.

UPDATE: after talking in comments to some people about follow up issues it seems that the issue was with switch statement scopes and just had to block the section of the code and working like a treat now, thank you everyone.

Rory Thoman
  • 69
  • 12
  • 1
    You are passing a vector type definition, not an actual object. You need to actually create a splitstring variable and pass that to split. –  May 16 '15 at 07:55
  • how would I do that? splitstring = null; after it to initialize it? – Rory Thoman May 16 '15 at 08:02
  • What is the input format? You're mixing up a lot of styles (not to mention namespaces), and I think the job can be done MUCH cleaner. If you post a purer question (without [X/Y problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) layers) you could get more quality advice. Just make it a SSCCE – sehe May 16 '15 at 08:03
  • input format is incredibly stupid, but it was sent by lecturer where the first two input variables are white space split but later variable are string with spaces. – Rory Thoman May 16 '15 at 08:04
  • @RoryThoman Sadly "the input format is incredibly stupid" isn't accurate enough for me to be able to implement. (I didn't ask you to blame some external party for the mess you have :) I suggested to focus on the task so I could help you clean it.) – sehe May 16 '15 at 08:12
  • RS e01 \n Alex Ferguson \n 3 Old Trafford Lane \n Hume \n 3008 \n 12345 \n 10/10/2015 1000.00 \n comments doesn't show '\n' so I have written it in – Rory Thoman May 16 '15 at 08:18
  • And _that_ would be excellent material to put in your question... I'm going to leave here. It seems you had all the help you need. Good luck – sehe May 16 '15 at 08:20

2 Answers2

2

You seem to be following an example similar to the one from the Boost documentation, but are missing a line.

typedef vector < string > splitstring;
splitstring stringthathasbeensplit;
boost::split(stringthathasbeensplit, *pos, boost::is_any_of(" "));

The problem is, you're declaring that splitstring is an alias for the type vector<string>. split will take an object of vector<string> type, but not the definition itself - which is what you are passing it by passing splitstring.

Really, you should just drop the typedef all together and directly declare an object of type vector<string>, as the typedef serves no purpose in this context. If you remove the typedef keyword, it will work as you have it written.

vector < string > splitstring;
boost::split(splitstring, *pos, boost::is_any_of(" "));
  • 1
    @RoryThoman don't do this. Make a self-contained question and post as new. Changing the question is exceptionally poor form (it invalidates the answers, when really you had no clear question) – sehe May 16 '15 at 08:14
  • the only difference is the error message, I am still after the exact same thing the title says and this error message was one I got before playing around with this same thing. so in my mind it is the same question, if i wrote a new question it would be the exact same title. and I feel creating a new one would be kinda spamming – Rory Thoman May 16 '15 at 08:16
  • Yeah. I realize from your -other- comment that you run into switch/case scope issues. (This is why your question needs to be selfcontained! So we can fix all the "follow-up" things too. Comment threads truly don't work for this). Just post the error in a comment then, if it's so trivial. – sehe May 16 '15 at 08:18
  • I believe your new issue is something weird connected to the switch, which I avoid like the plague. Try moving the splitstring declaration above the opening of the switch statement. Also see: http://stackoverflow.com/questions/2392655/what-are-the-signs-of-crosses-initialization –  May 16 '15 at 08:21
1

It's pretty weird to have a type definition inside your function. I suspect you are just trying to define a variable of type std::vector<std::string>. To do so, you can simply write:

std::vector<std::string> splitstring;

You would replace the typedef line with that line.

EDIT: Another issue is that you are trying to define this object inside a switch statement, which is similar to a bunch of "goto" statements and labels. You should put the object in its own scope so that there are no codepaths that jump into the middle of its scope, or else you will get compiler errors. To do that, just surround the object definition and any code that uses it with an extra set of brackets:

   case 6:
        {
            std::vector<std::string> splitstring;
            boost::split(splitstring, *pos, boost::is_any_of(" "));
            if (splitstring[0] == "RS") {
                propertyType = new ResSales;
            } else if (splitstring[0] == "RS") {
                propertyType = new ResRentals;
            } else {
                return false;
            }
        }
        break;

Disclaimer: I have not tested this code and there might be other errors or typos that I have not noticed.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • 1
    Why on earth is it "weird" to define a type alias locally? This happens _all the time_ – sehe May 16 '15 at 07:59
  • need typedef there otherwise boost::split() function can not see it. – Rory Thoman May 16 '15 at 08:00
  • yes sorry I have been messing around with it a lot and got a lot of errors and forgot what error lined up with what solution i tried. removing the typedef and cleaning the code back up to standard I get the error "jump to case label" and "cross initialization of vector > – Rory Thoman May 16 '15 at 08:09
  • @RoryThoman give the variable a scope of its own. The switch has funny variable scope rules – sehe May 16 '15 at 08:17
  • sorry I am still learning about c++ how would I give it it's own scope in a switch statement? – Rory Thoman May 16 '15 at 08:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77956/discussion-between-sehe-and-rory-thoman). – sehe May 16 '15 at 08:21
  • Sehe made a good point about putting the variable in is own scope. I have edited my answer. – David Grayson May 16 '15 at 18:23