关于数组:C++用字符分割字符串

c++ Split string by a character?

本问题已经有最佳答案,请猛点这里访问。

如何用"EDOCX1"〔1〕字符拆分"EDOCX1"〔0〕这样的字符串,最好将所有的数字放入一个int数组(数字序列总是8长),而不使用外部库,如boost。

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


stringstream可以做到所有这些。

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

    1
    2
    3
    4
    5
    6
    7
    8
    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}
  • 在处理之前,从字符串中删除不需要的字符,如$#:正如上面处理:的方法一样。


  • C语言中的标准方法是像其他人回答的那样使用strtok。然而,strtokC++不同,也不安全。C++中的标准方法是使用EDCOX1〔7〕。

    1
    2
    3
    4
    5
    6
    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可能是另一个简单的解决方案。

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


    我以前不得不写一些这样的代码,在堆栈溢出中发现了一个问题,即用分隔符拆分字符串。这是最初的问题:链接。

    您可以将它与std::stoi一起用于构建向量。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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示例。


    这是一条路…不是最聪明的,但写起来很快(8次重复几乎保证了一个循环)。这种解析方法非常有用,学习起来非常好。!(iss >> c)确保字符串中没有尾随的非空白字符。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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))
        ...


    要删除字符""和"$",可以使用标准算法std::remove_if。但是,考虑到如果有以下字符串"12_34",那么在删除""之后,您将得到"1234"。如果需要,结果字符串将显示为"12 34"或"12:34",那么最好使用std::replace_if,而不是std::remove_if

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include

    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 = '\0';

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

    输出是

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include
    #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;
    }


    包括

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <string.h>

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

    真的!没有精灵魔法

    它也有点回答这里

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #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;
    }

    这里演示


    您可以使用strtok()来分割您的字符串,可能是在while循环中。

    当您得到单个字符串时,就可以使用atoi(xxx)在ints中进行转换。