【问题标题】:spliting a string twice using boost in C++?在 C++ 中使用 boost 将字符串拆分两次?
【发布时间】:2015-05-16 07:44:59
【问题描述】:

我正在尝试使用分隔符从文件中拆分数据,但之后我想再次使用空格拆分某些字符串,但我一直遇到编译器错误。这段代码如下...

PS:我没有共享所有代码,所以如果它看起来不完整,这就是原因,我只是在寻找一种重新拆分所选字符串的方法。

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;
}

基本上,如果 case 是 6,我想再次用空格分割令牌,我不知道如何实现这一点,我正在尝试使用 boost,如你所知。但我得到了错误....

非常感谢任何帮助,谢谢。

更新:在 cmets 与一些人讨论后续问题后,似乎问题出在 switch 语句范围内,现在只需要阻止代码部分并像对待一样工作,谢谢大家。

【问题讨论】:

  • 您传递的是 vector 类型定义,而不是实际对象。您需要实际创建一个拆分字符串变量并将其传递给拆分。
  • 我该怎么做?拆分字符串=空;在它初始化它之后?
  • 输入格式是什么?你混合了很多样式(更不用说命名空间了),我认为这项工作可以做得更干净。如果您发布更纯粹的问题(没有X/Y problem 层),您可以获得更多质量建议。让它成为 SSCCE
  • 输入格式非常愚蠢,但它是由讲师发送的,其中前两个输入变量是空格分割,但后面的变量是带空格的字符串。
  • @RoryThoman 遗憾的是,“输入格式非常愚蠢”对我来说还不够准确,无法实现。 (我没有让你把你的烂摊子归咎于某个外部团体:)我建议专注于这项任务,这样我就可以帮助你清理它。)

标签: c++ string boost split token


【解决方案1】:

您似乎在遵循与Boost documentation 中的示例类似的示例,但缺少一行。

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

问题是,您声明splitstringvector&lt;string&gt; 类型的别名。 split 将采用 vector&lt;string&gt; 类型的 object,而不是 定义 本身 - 这就是您通过 splitstring 传递的内容。

真的,您应该将typedef 全部删除并直接声明vector&lt;string&gt; 类型的对象,因为typedef 在这种情况下没有任何作用。如果您删除 typedef 关键字,它将按照您编写的方式工作。

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

【讨论】:

  • @RoryThoman 不要这样做。提出一个独立的问题并作为新问题发布。更改问题是非常糟糕的形式(它会使答案无效,当你真的没有明确的问题时)
  • 唯一的区别是错误信息,我仍然追求标题所说的完全相同的东西,而这个错误信息是我在玩同样的东西之前得到的。所以在我看来这是同一个问题,如果我写了一个新问题,那将是完全相同的标题。我觉得创建一个新的会有点垃圾邮件
  • 是的。我从您的 -other- 评论中意识到您遇到了开关/案例范围问题。 (这就是为什么您的问题需要独立的原因!所以我们也可以修复所有“后续”问题。评论线程确实不适用于此)。只需在评论中发布错误,如果它是如此微不足道的话。
  • 我相信您的新问题是与交换机有关的奇怪问题,我会像瘟疫一样避免这种情况。尝试将 splitstring 声明移到 switch 语句的开头。另请参阅:stackoverflow.com/questions/2392655/…
【解决方案2】:

在你的函数中有一个类型定义是很奇怪的。我怀疑你只是想定义一个std::vector&lt;std::string&gt; 类型的变量。为此,您可以简单地编写:

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

您可以用该行替换 typedef 行。

编辑:另一个问题是你试图在 switch 语句中定义这个对象,这类似于一堆“goto”语句和标签。你应该把对象放在它自己的作用域中,这样就没有代码路径跳转到它的作用域中间,否则你会得到编译器错误。为此,只需将对象定义和使用它的任何代码用一组额外的括号括起来:

   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;

免责声明:我没有测试过这段代码,可能还有其他我没有注意到的错误或拼写错误。

【讨论】:

  • 为什么在本地定义类型别名是“奇怪的”?这种情况一直发生
  • 那里需要typedef,否则boost::split()函数看不到。
  • 是的,对不起,我一直在搞砸它,遇到了很多错误,忘记了我尝试的解决方案是什么错误。删除 typedef 并将代码清理回标准我收到错误“跳转到案例标签”和“向量的交叉初始化 >
  • @RoryThoman 给变量一个它自己的范围。开关有有趣的变量范围规则
  • 对不起,我还在学习 c++,如何在 switch 语句中给它自己的范围?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
相关资源
最近更新 更多