C++ 按字符拆分字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20755140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:18:09  来源:igfitidea点击:

Split string by a character?

c++arraysstringsplittokenize

提问by user2705775

How can I split a string such as "102:330:3133:76531:451:000:12:44412by the ":"character, and put all of the numbers into an int array (number sequence will always be 8 elements long)? Preferably without using an external library such as boost.

如何"102:330:3133:76531:451:000:12:44412":"字符拆分字符串,并将所有数字放入一个 int 数组(数字序列的长度始终为 8 个元素)?最好不使用外部库,例如 boost。

Also, I'm wondering how I can remove unneeded characters from the string before it's processed such as "$" and "#"?

另外,我想知道如何在处理字符串之前从字符串中删除不需要的字符,例如“$”和“#”?

采纳答案by herohuyongtao

stringstreamcan do all these.

stringstream这些都可以。

  1. Split a string and store into int array:

    string str = "102:330:3133:76531:451:000:12:44412";
    std::replace(str.begin(), str.end(), ':', ' ');  // replace ':' by ' '
    
    vector<int> array;
    stringstream ss(str);
    int temp;
    while (ss >> temp)
        array.push_back(temp); // done! now array={102,330,3133,76531,451,000,12,44412}
    
  2. Remove unneeded characters from the string before it's processed such as $and #: just as the way handling :in the above.

  1. 拆分字符串并存储到 int 数组中:

    string str = "102:330:3133:76531:451:000:12:44412";
    std::replace(str.begin(), str.end(), ':', ' ');  // replace ':' by ' '
    
    vector<int> array;
    stringstream ss(str);
    int temp;
    while (ss >> temp)
        array.push_back(temp); // done! now array={102,330,3133,76531,451,000,12,44412}
    
  2. 在处理之前从字符串中删除不需要的字符,例如$#: 就像:上面的处理方式一样。

PS: The above solution works only for strings that don't contain spaces. To handle strings with spaces, please refer to herebased on std::string::find()and std::string::substr().

PS:上述解决方案仅适用于不包含空格的字符串。要处理带空格的字符串,请参考这里基于std::string::find()std::string::substr()

回答by phuclv

The standard way in C is using strtoklike others have answered. However strtokis not C++-like and also unsafe. The standard way in C++ is using std::istringstream

C 中的标准方法是strtok像其他人回答的那样使用。然而strtok,不一样C++,也不安全。C++ 中的标准方法是使用std::istringstream

std::istringstream iss(str);
char c; // dummy character for the colon
int a[8];
iss >> a[0];
for (int i = 1; i < 8; i++)
    iss >> c >> a[i];

In case the input always has a fixed number of tokens like that, sscanfmay be another simple solution

如果输入总是有固定数量的令牌,sscanf可能是另一个简单的解决方案

std::sscanf(str, "%d:%d:%d:%d:%d:%d:%d:%d", &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8);

回答by Lander

I had to write some code like this before and found a question on Stack Overflow for splitting a string by delimiter. Here's the original question: link.

我之前不得不写一些这样的代码,并在 Stack Overflow 上发现了一个问题,用于按分隔符拆分字符串。这是原始问题:link

You could use this with std::stoifor building the vector.

您可以使用它std::stoi来构建向量。

std::vector<int> split(const std::string &s, char delim) {
    std::vector<int> elems;
    std::stringstream ss(s);
    std::string number;
    while(std::getline(ss, number, delim)) {
        elems.push_back(std::stoi(number));
    }
    return elems;
}

// use with:
const std::string numbers("102:330:3133:76531:451:000:12:44412");
std::vector<int> numbers = split(numbers, ':');

Here is a working ideone sample.

这是一个工作 ideone 示例

回答by Tony Delroy

Here's one way... not the cleverest but fast to write (8 repetition's verging on warranting a loop though). This approach to parsing is quite widely useful so good to learn. !(iss >> c)ensures there's no trailing non-whitespace characters in the string.

这是一种方法......不是最聪明但写起来很快(尽管8次重复接近保证循环)。这种解析方法非常有用,值得学习。 !(iss >> c)确保字符串中没有尾随的非空白字符。

std::istringstream iss(the_string);
char c;
int n[8];
if (iss >> n[0] >> c && c == ':' &&
    iss >> n[1] >> c && c == ':' &&
    iss >> n[2] >> c && c == ':' &&
    iss >> n[3] >> c && c == ':' &&
    iss >> n[4] >> c && c == ':' &&
    iss >> n[5] >> c && c == ':' &&
    iss >> n[6] >> c && c == ':' &&
    iss >> n[7] && !(iss >> c))
    ...

回答by Digital_Reality

You can use strtok()for split your string, perhaps in while loop.

您可以使用strtok()for 拆分字符串,也许在 while 循环中。

When you get individual string then can use atoi(xxx)for conversion in ints.

当您获得单个字符串时,可以atoi(xxx)用于整数转换。

回答by P0W

True ! there's no elven magic

真的 !没有精灵魔法

Its kinda answered heretoo

它有点回答这里

#include <cstring>
#include <iostream>
#include<cstdlib>
#include<vector>

int main() 
{
    char input[100] = "102:330:3133:76531:451:000:12:44412";
    char *token = std::strtok(input, ":");
    std::vector<int> v;

    while (token != NULL) {
        v.push_back( std::strtol( token, NULL, 10 ));
        token = std::strtok(NULL, ":");
    }

    for(std::size_t i =0 ; i < v.size() ; ++i)
        std::cout << v[i] <<std::endl;
}

Demo Here

演示在这里

回答by Imtiaz Emu

#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="102:330:3133:76531:451:000:12:44412";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str,":");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, ":");
  }
  return 0;
}

回答by user515430

Another solution using the regular expression features in C++11.

另一种使用 C++11 中的正则表达式功能的解决方案。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <regex>
#include <sstream>
#include <string>
#include <vector>

int main()
{
    const std::string s = "102:330:3133:76531:451:000:12:44412";

    // Replace each colon with a single space
    const std::regex pattern(":");
    const std::string r = std::regex_replace(s, pattern, " ");

    std::istringstream ist(r);

    std::vector<int> numbers;
    std::copy(std::istream_iterator<int>(ist), std::istream_iterator<int>(),
        std::back_inserter(numbers));

    // We now have a vector of numbers

    // Print it out
    for (auto n : numbers)
    {
        std::cout << n << " ";
    }
    std::cout << std::endl;

    return 0;
}

回答by Vlad from Moscow

To remove characters '#' and '$' you can use standard algorithm std::remove_if. However take into account that if there is for example the following string "12#34" then after removing '#' you will ge "1234". If you need that the resulted string will look as "12 34" or "12:34" then instead of std::remove_ifit is better to use std::replace_if.

要删除字符 '#' 和 '$',您可以使用标准算法std::remove_if。但是请注意,如果有以下字符串“12#34”,那么在删除“#”后,您将得到“1234”。如果您需要结果字符串看起来像“12 34”或“12:34”,那么std::remove_if最好使用std::replace_if.

Below there is a sample code that performs the task. You need to include headers

下面是执行任务的示例代码。您需要包含标题

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>

int main()
{
    char s[] = "102:$0:#3133:76531:451:000::44412";

    std::cout << s << std::endl;

    char *p = std::remove_if( s, s + std::strlen( s ), 
        []( char c ) { return ( c == '$' || c == '#' ); } );
    *p = '
102:$0:#3133:76531:451:000::44412
102:330:3133:76531:451:000:12:44412
102 330 3133 76531 451 0 12 44412
'; std::cout << s << std::endl; const size_t N = 8; int a[N]; p = s; for ( size_t i = 0; i < N; i++ ) { a[i] = strtol( p, &p, 10 ); if ( *p == ':' ) ++p; } for ( int x : a ) std::cout << x << ' '; std::cout << std::endl; }

The output is

输出是

##代码##