按字符拆分字符串

Split string by a character?

本文关键字:字符串 拆分 字符      更新时间:2023-10-16

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

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

stringstream可以做到所有这些。

  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:上述解决方案仅适用于不包含空格的字符串。要处理带空格的字符串,请参阅此处基于std::string::find()std::string::substr()

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

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

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

之前不得不编写一些这样的代码,并在 Stack Overflow 上发现了一个问题,用于通过分隔符拆分字符串。这是最初的问题:链接。

您可以将其与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, ':');

这是一个工作 ideone 示例。

真的! 没有精灵魔法

它在这里也有点回答

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

在这里演示

要删除字符"#"和"$",您可以使用标准算法std::remove_if。但是要考虑到,如果例如有以下字符串"12#34",那么在删除"#"后,您将 ge "1234"。如果您需要结果字符串看起来像"12 34"或"12:34",那么最好使用 std::replace_if 而不是std::remove_if

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

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
int main()
{
    char s[] = "102:$$330:#3133:76531:451:000:$12:44412";
    std::cout << s << std::endl;
    char *p = std::remove_if( s, s + std::strlen( s ), 
        []( char c ) { return ( c == '$' || c == '#' ); } );
    *p = '';
    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;
}

输出为

102:$$330:#3133:76531:451:000:$12:44412
102:330:3133:76531:451:000:12:44412
102 330 3133 76531 451 0 12 44412

这是一种方式...不是最聪明的,但写起来很快(虽然 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))
    ...
您可以使用

strtok()来拆分字符串,也许在while循环中。

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

使用 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;
}
#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 ("%sn",pch);
    pch = strtok (NULL, ":");
  }
  return 0;
}