Rory Thoman
Rory Thoman

Reputation: 69

spliting a string twice using boost in C++?

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.

Upvotes: 0

Views: 243

Answers (2)

David Grayson
David Grayson

Reputation: 87386

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.

Upvotes: 1

user3995702
user3995702

Reputation:

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(" "));

Upvotes: 2

Related Questions