C++ 在C+;中的两个定界符上拆分字符串+;

C++ 在C+;中的两个定界符上拆分字符串+;,c++,string,C++,String,我有一个文件cities.txt,包含: Hayward - San Lorenzo San Lorenzo - Oakland Dublin - San Jose San Mateo - Hayward San Francisco - Daly City San Mateo - Oakland San Francisco - Oakland Freemont - Hayward San Lorenzo - Dublin San Jose - San Mateo Daly City - San

我有一个文件cities.txt,包含:

Hayward - San Lorenzo
San Lorenzo - Oakland
Dublin - San Jose
San Mateo - Hayward
San Francisco - Daly City
San Mateo - Oakland
San Francisco - Oakland
Freemont - Hayward
San Lorenzo - Dublin
San Jose - San Mateo
Daly City - San Raphael
我阅读了该文件的内容:

#include <iostream>
#include <fstream>
#include <string>
#include <iterator>



int main( ) {
    std::ifstream infile( "cities.txt" ) ;
    if ( infile ) {
        std::string fileData( ( std::istreambuf_iterator<char> ( infile ) ) ,
        std::istreambuf_iterator<char> ( ) ) ;
        infile.close( );
        std::cout << fileData <<"\n\n";
        return 0 ;
   }
   else {
      std::cout << "Where is cities.txt?\n" ;
      return 1 ;
   }
}
我本来打算将字符串转换成char*并使用strtok,但似乎有很多工作要做,可能可以使用标准字符串函数来完成。
有没有一种既快速又简洁的方法呢?

我可能会使用
std::getline
,指定
-
作为元素之间的分隔符:

std::string city;
while (std::getline(i, city, '-'))
    cities.push_back(city);

一个小细节:这将保留完整的空白,因此如果前导和/或尾随空白有问题,则必须分别对其进行修剪。

您可以使用string::find、string::erase和string::substr

使用类似的while循环

发现=输入。发现(“-”);
while(found!=string::npos){…}


在城市名称的while子字符串中,然后使用.erase(位置,长度)从整个字符串中删除城市。

您可以使用boost regex\u split。我已经修改了您的代码以演示相同的功能。贴在下面:

#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <boost/regex.hpp>
#include <vector>



int main( ) {
    std::ifstream infile( "cities.txt" ) ;
    if ( infile ) {
        std::string fileData( ( std::istreambuf_iterator<char> ( infile ) ) ,
        std::istreambuf_iterator<char> ( ) ) ;
        infile.close( );
        std::cout << fileData <<"\n\n";
        std::vector<std::string> out;

        // Delimeter regular expression
        boost::regex delims("\\s+-\\s+|\n|\r");

        boost::regex_split(std::back_inserter(out), fileData, delims);
        for (auto &city : out) {
            std::cout << city << std::endl;
        }
   }
   else {
      std::cout << "Where is cities.txt?\n" ;
      return 1 ;
   }
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
std::ifstream infle(“cities.txt”);
如果(填充){
std::string文件数据((std::istreambuf_迭代器(infle)),
std::istreambuf_迭代器();
infle.close();

std::cout您可以通过两个步骤完成此操作

  • 将文件内容拆分为字符串向量-因此,向量的每个元素将包含文件的一行

  • 将文件的每一行拆分为两个元素(行中有两个城市)

  • 修剪内容

  • 拆分功能可以这样实现:

    list = {"Hayward","San Lorenzo", "San Lorenzo", "Oakland"......}
    
    vector<string> split (string str, string seq) { 
        vector<string> ret {};
        size_t pos {};
    
        while ((pos = str.find (seq)) != string::npos) { 
            ret.push_back (str.substr (0, pos));
            str = str.substr (pos+seq.size ()); 
        }
        ret.push_back (str);
    
        return ret;
    }
    
    string ltrim (string s) { 
        s.erase (s.begin (), find_if (s.begin (), s.end (), not1 (ptr_fun<int, int> (isspace))));
        return s;
    }
    
    string rtrim (string s) { 
        s.erase (find_if (s.rbegin (), s.rend (), not1 (ptr_fun<int, int> (isspace))).base (), s.end ());
        return s;
    }
    
    string trim (string s) { 
        return ltrim (rtrim (s));
    }
    
    现在需要一些解释。让我们看一下<强>(1)< /强>,我们取文件的整个内容(我错过了从文件中检索内容),并创建一个字符串向量,在这种情况下,它是行的向量(来自文件),因为<强> SEQ < /强> uN是“\n”)。.那么,我们从文件中传递到行的结果函数向量。好的,很简单,让我们继续。现在我们必须将这一行分成两个字符串(城市)(2),但是我们的seq现在是“-”。这(2)调用将生成字符串向量,其中将包含城市名称。现在,我们所要做的就是将这些名称添加到将返回的向量ret,但首先修剪内容,以消除左右两侧的所有空白

    结果是:

    |Hayward|
    |San Lorenzo|
    |San Lorenzo|
    |Oakland|
    |Dublin|
    |San Jose|
    |San Mateo|
    |Hayward|
    |San Francisco|
    |Daly City|
    |San Mateo|
    |Oakland|
    |San Francisco|
    |Oakland|
    |Freemont|
    |Hayward|
    |San Lorenzo|
    |Dublin|
    |San Jose|
    |San Mateo|
    |Daly City|
    |San Raphael|
    
    auto vec = result (split (content, "\n")); // (1)
    show (vec);
    
    |Hayward|
    |San Lorenzo|
    |San Lorenzo|
    |Oakland|
    |Dublin|
    |San Jose|
    |San Mateo|
    |Hayward|
    |San Francisco|
    |Daly City|
    |San Mateo|
    |Oakland|
    |San Francisco|
    |Oakland|
    |Freemont|
    |Hayward|
    |San Lorenzo|
    |Dublin|
    |San Jose|
    |San Mateo|
    |Daly City|
    |San Raphael|