我在将字符串拆分为向量时遇到困难

时间:2019-09-25 19:50:49

标签: c++ string vector split push-back

我正在尝试编写通过在每个空格字符处将字符串分割为矢量来将字符串初始化为矢量的代码。临时矢量不知何故不会占据位置,也不会正确分割字符串。

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> splitStr(std::string s, char cut = 32) {
    std::string temp = s;
    int begin = 0;
    std::vector<std::string> v;
    for (int i = 0; i < temp.length() - 1; ++i) {
        if ((int) cut == (int) temp[i]) {
            v.push_back(temp.substr(begin, i));
            begin = i + 1;
        }
    }
    return v;
}


using namespace std;


int main() {

    for (string e : splitStr("Hello this is a test!", ' ')) {
        cout << e << endl;
    }

}

我认为附加到向量上会出错,但是我不知道为什么。 你们可以告诉我我在做什么错吗?

3 个答案:

答案 0 :(得分:0)

substr的第二个参数是您要从原始字符串中选取的字符数,如果未传递,它将带走所有字符,直到字符串结尾。这是经过更正的代码:

  std::vector<std::string> splitStr(std::string s, char cut = 32) {
    std::string temp = s;
    int begin = 0;
    // Remove multiple spaces based on logic described here : https://stackoverflow.com/questions/8362094/replace-multiple-spaces-with-one-space-in-a-string
    std::string::iterator new_end = std::unique(temp.begin(), temp.end(), [](char one,char two) { return (one == two) && (one == ' '); } );
    temp.erase(new_end, temp.end());
    std::vector<std::string> v;
    for (int i = 0; i < temp.length() - 1; ++i) {
        if ((int) cut == (int) temp[i]) {
            v.push_back(temp.substr(begin, i-begin));
            begin = i + 1;
        }
    }
    v.push_back(temp.substr(begin));
    return v;
}
    using namespace std;


    int main() {

        for (string e : splitStr("Hello this is a test!", ' ')) {
            cout << e << endl;
        }

    }

答案 1 :(得分:0)

对于初学者,请勿使用32等魔术数字。

第二,制表符也可以视为空白分隔符。第一个参数应该是对字符串的const引用。

无需在函数内创建参数的副本。

此循环

for (int i = 0; i < temp.length() - 1; ++i) {
    if ((int) cut == (int) temp[i]) {
        v.push_back(temp.substr(begin, i));
        begin = i + 1;
    }
}

没有道理。例如,字符串可以包含两个连续的空格。其次,调用substr temp.substr(begin, i)的第二个参数无效。它应指定子字符串的长度,

使用类std::string的标准搜索成员函数代替循环。

这里是一个演示程序,显示了如何实现该功能。

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> splitStr( const std::string &s, 
                                   const std::string &delim = " \t" )
{
    std::vector<std::string> v;

    for ( std::string::size_type pos = 0, n = 0;
          ( pos = s.find_first_not_of( delim, pos ) ) != std::string::npos; 
          pos += n )
    {
        n = s.find_first_of( delim, pos );

        n = ( n == std::string::npos ? s.size() : n ) - pos;

        v.push_back( s.substr( pos, n ) );
    }

    return v;
}

int main() 
{
    for ( const auto &s : splitStr( "Hello this is a test!" ) )
    {
        std::cout << s << std::endl;
    }

    return 0;
}

其输出为

Hello
this
is
a
test!

答案 2 :(得分:0)

  

在每个空格字符处将其分隔

这会将其分割为每个空格字符。我已经对代码的更改发表了评论。

#include <iostream>
#include <string>
#include <vector>

// don't use magic numbers like 32 for space. Use a literal space: ' '

// Instead of copying the string (potentially twice), use a reference to
// your input parameter and make it const if you are not going to change it.

std::vector<std::string> splitStr(const std::string& temp, char cut = ' ') {
    // Use types designed for the task to avoid casting, like
    // size_t for most indexing tasks.
    size_t begin = 0;
    std::vector<std::string> v;

    // with temp.length()-1 you won't capture a space at the very end
    for(size_t i = 0; i < temp.length(); ++i) {
        if(cut == temp[i]) {
            // the second argument to substr is the length of the sub string
            v.push_back(temp.substr(begin, i - begin));
            begin = i + 1;
        }
    }
    // add the remaining part of the string
    v.push_back(temp.substr(begin));
    return v;
}

// using namespace std; // don't do this globally

int main() {
    // added double spaces between words and one at the end for effect
    for(const std::string& e : splitStr("Hello  this  is  a  test! ", ' ')) {
        // added > and < around the words to see what you captured
        std::cout << '>' << e << '<' << std::endl;
    }
}

输出:

>Hello<
><
>this<
><
>is<
><
>a<
><
>test!<
><