我有一个文件,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,但是似乎可以使用标准字符串函数完成很多工作。 有没有办法既快速又简洁?

===============>>#1 票数:2 已采纳

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

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

一个小细节:这将保留空白,因此,如果前导和/或尾随空白是一个问题,则必须单独进行修剪。

===============>>#2 票数:2

您可以分两步执行此操作。

  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|

===============>>#3 票数:1

您可以使用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)从整个字符串中删除城市

===============>>#4 票数:1

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

  ask by ostochast translate from so

未解决问题?本站智能推荐:

3回复

使用2个分隔符“+”和“ - ”在C ++中拆分字符串

我试图用C ++中的2个分隔符'+'和' - '分割一个字符串,使用字符串查找分隔符... 任何人都可以给我一个... 运用 str.find(分隔符) 例如: A + B-C + d 需要输出:abcd 提前致谢
1回复

从C ++中的字符串中提取两个分隔符之间的子字符串

如果子字符串介于开始定界符和结束定界符之间,则必须从字符串中提取子字符串。 例如,我的字符串是: 起始定界符为“ _”,结束定界符为“&”。 我需要介于“ _”和“&”之间的所有子字符串。 即,我的输出应为: 我尝试使用boost :: tokenizer,但它也将字符
3回复

C ++使用单词列表作为分隔符拆分字符串

我想像这样拆分一个字符串 使用像一个波纹管这样的单词列表 进入这个清单 分隔符允许在要拆分的字符串中出现多次,并且可以使用正则表达式来完成 优先顺序是定界符在数组中出现的顺序 我正在开发的平台不支持Boost库 更新资料 这就是我目前所拥有的
5回复

如何用两个不同的分隔符分割字符串[重复]

这个问题已经在这里有了答案: 用多个定界符将字符串拆分成单词 6个答案 我想将数据存储在对象数组中,但是我不知道如何分割字符串。 我想看到的结果是: 这是我的字符串的外观: 我目前拥有的代码,仅允许您拆分而不管理管道: 谢谢前进
7回复

使用空格作为分隔符将字符串拆分为C / C ++中的字符串数组的更好方法

对不起,我的C / C ++不是那么好,但是对我来说,下面的现有代码看起来像垃圾。 它也有一个错误 - 当str =“07/02/2010”由'\\ 0'终止时失败 - 。 我认为不是修复错误,而是可以重写。 在Python中,它只是'kas\\nhjkfh kjsdjkasf'.spli
3回复

使用多个分隔符进行快速字符串拆分

我在StackOverflow上调查了一段时间,找到了将多个分隔符的字符串拆分成vector< string >好算法。 我还发现了一些方法: 推动方式: getline方法: Boost的标记化方式: 和酷STL方式: 和Shadow2531
3回复

C ++中的字符串标记器,允许多个分隔符

有没有办法在C ++中使用多个分隔符来标记字符串? 在C#中,我应该这样做:
2回复

分割字符串-多个分隔符C ++

因此,此用户将所有输入都放在一行字符串中,我需要将输入解析为两类:用户年龄和用户名。 例如,用户输入->> [23:Frank] [15:Jack] [45:] [33:sofia] []在这种情况下,我有多个参数(定界符,共3个),它们是[ :],此外,一旦我在结尾遇到[],就需
1回复

C ++字符串和分隔符

这个问题已经在这里有了答案: 如何遍历字符串中的单词? 76个答案 所以我正在做一个程序,在其中我将一些数据输入文件并从中读取。 问题是我不知道该如何处理。 我从文件中读取并接收到一个字符串,其中包含许多由定界符“ |”分隔的不同数据。 所以我的问题是
1回复

C ++ int和带分隔符的字符串解析

我试图找到一种方法来分割字符串来查找数字和特定的单词。 在这里,我试图读取苹果和橘子的数量。 但是,我写这个的方式,如果单词“apple”或“orange”之前或之后是标点符号,它将不计算在内。 例如,考虑文本文件: 3个苹果2个橘子 3个苹果。 2个橘子。 (3个苹果2个