簡體   English   中英

在C ++中的兩個分隔符上拆分字符串

[英]Splitting a string on two delimitators in C++

我有一個文件,citys.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 ;
   }
}

並將內容保存在fileData字符串中。 我需要將該字符串分成僅包含城市名稱的字符串列表。 像這樣:

list = {"Hayward","San Lorenzo", "San Lorenzo", "Oakland"......}

我打算將字符串轉換為char *並使用strtok,但是似乎可以使用標准字符串函數完成很多工作。 有沒有辦法既快速又簡潔?

我可能會使用std::getline ,將-指定為元素之間的分隔符:

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

一個小細節:這將保留空白,因此,如果前導和/或尾隨空白是一個問題,則必須單獨進行修剪。

您可以分兩步執行此操作。

  1. 將文件的內容分割為字符串向量-因此,向量的每個元素將包含文件的單行

  2. 將文件的每一行拆分為兩個元素(該行中的兩個城市)

  3. 修剪內容

split函數可以這樣實現:

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

因此,基本上,您有了所有需要的東西,讓我們准備一個結果函數。

vector<string> result (vector<string>&& content) {
    vector<string> ret {};
    for (const auto& c : content) { 
        auto vec = split (c, "-"); // (2)
        for (const auto& v : vec) { 
            ret.push_back (trim (v));
        }

    }
    return ret;
}

void show (const vector<string>& vec) { 
    for (const auto& v : vec) { 
        cout << "|" << v << "|" << endl;
    }
}

並假設文件內容位於content對象中,使用情況如下所示。

auto vec = result (split (content, "\n")); // (1)
show (vec);

現在,需要一些解釋。 讓我們來看看(1)我們把文件的全部內容(我錯過了檢索從文件的內容),並創建一個字符串矢量,在這種情況下,它是一個行向量(從文件,因為以次 uence是“\\ n”)。 因此,我們將傳遞文件中行的結果函數向量。 好吧,簡單,讓我們繼續。 現在我們就來此行分成兩個字符串(市)(2),但我們的SEQ uence現在是“ - ”。 (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|

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

使用while循環,類似於found = input.find("-"); while(found != string::npos){... } found = input.find("-"); while(found != string::npos){... }

在while子字符串中輸入城市名稱,然后使用.erase(position,length)從整個字符串中刪除城市

您可以使用boost regex_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 ;
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM