简体   繁体   English

我将如何分隔我正在寻找的超过 1 个字符的 std::string ?

[英]How would I separate a std::string with more than 1 character I'm looking for?

I'm writing a program that can take in multiple names separated by a space, like "John Paul Andrew" and turns the names into keys for a std::map.我正在编写一个程序,它可以接收多个由空格分隔的名称,例如"John Paul Andrew" ,并将名称转换为 std::map 的键。

It works fine with two names, but three names or more separate the string into:它适用于两个名称,但三个或更多名称将字符串分隔为:

Andrew
John
John Paul

Here's how I'm splitting the strings:这是我拆分字符串的方式:

for (int i = 0; i < names.size() - 1; i++) {
        std::string::size_type pos = names.find(" ", i);

        std::cout << "Position of space: " << pos << std::endl; // For debugging

        if (pos != std::string::npos) {
            std::string name = names.substr(0, pos);
            scoreboard[name] = 0;
        } else {
            std::string name = names.substr(names.rfind(" ") + 1);
            scoreboard[name] = 0;
        }

}

Is there a replacement for names.substr(0, pos);是否有names.substr(0, pos);的替代品? I can use to fix the issue?我可以用来解决问题吗?

You have i as you indexer, which can help you find the word being processed.你有i作为你的索引器,它可以帮助你找到正在处理的单词。 So you don't need an old_pos as I had suggested, since i already can serve that purpose.所以你不需要我建议的old_pos ,因为i已经可以达到这个目的。

#include <iostream>
#include <string>
#include <map>

using std::cout;
using std::map;
using std::string;

static auto make_scoreboard(string names) -> map<string, int> {
    auto scoreboard = map<string, int>{};

    for (decltype(names.size()) i = 0; i < names.size() - 1; i++) {
        auto pos = names.find(" ", i);

        cout << "Position of space: " << pos << "\n"; // For debugging

        if (pos != string::npos) {
            auto name = names.substr(i, pos - i);
            scoreboard[name] = 0;
            i = pos;
        } else {
            string name = names.substr(names.rfind(" ") + 1);
            scoreboard[name] = 0;
            i = names.size();
        }
    }

    return scoreboard;
}


int main() {
    auto names = string{"John Paul Andrew"};
    auto scoreboard = make_scoreboard(names);

    for(auto&& s : scoreboard) {
        cout << s.first << "\n";
    }
}

You are looping through each character of names (except the last character,), using the current loop position as the starting position to find() a space character.您正在遍历names每个字符最后一个字符除外),使用当前循环 position 作为起始position 来find()一个空格字符。 That is not the logic you should be using.这不是您应该使用的逻辑。

Let's follow the logic, using your example of "John Paul Andrew" as the names to split.让我们按照逻辑,使用您的"John Paul Andrew"示例作为要拆分的names

  • On the 1st-5th loop iterations, where i is 0..4 , names.find(" ", i) returns 4 each time.在第 1-5 次循环迭代中, i0..4names.find(" ", i)每次返回 4。 You then call names.substr(0, 4) which returns "John" .然后你调用names.substr(0, 4)返回"John" So you assign 0 to scoreboard["John"] 5 times .因此,您将 0 分配给scoreboard["John"] 5 次

  • On the 6th-10th loop iterations, where i is 5..9 , names.find(" ", i) returns 9 each time.在第 6-10 次循环迭代中, i5..9names.find(" ", i)每次返回 9。 You then call names.substr(0, 9) which returns "John Paul" .然后,您调用names.substr(0, 9)返回"John Paul" So you assign 0 to scoreboard["John Paul"] 5 times .因此,您将 0 分配给scoreboard["John Paul"] 5 次

  • On the 11th-15th loop iterations, where i is 10..14 , names.find(" ", i) returns std::string::npos each time.在第 11-15 次循环迭代中, i10..14names.find(" ", i)每次都返回std::string::npos You then call names.rfind(" ") which returns 9, and then you call names.substr(9 + 1) which returns "Andrew" .然后调用names.rfind(" ")返回 9,然后调用names.substr(9 + 1)返回"Andrew" So you assign 0 to scoreboard["Andrew"] 5 times .因此,您将 0 分配给scoreboard["Andrew"] 5 次

See the problem now?现在看到问题了吗?

At the very least, since you are looping through names one character at a time anyway, you should not be using names.find() at all, eg:至少,由于您一次遍历一个字符的names ,因此您根本不应该使用names.find() ,例如:

std::string::size_type start = 0;

for (std::string::size_type i = 0; i < names.size(); ++i) { // <-- no -1 !
    if (names[i] == ' ') {
        std::cout << "Position of space: " << i << std::endl; // For debugging
        if (i > start) {
            std::string name = names.substr(start, i - start);
            scoreboard[name] = 0;
        }
        start = i + 1;
    }
}

if (start < names.size()) {
    std::string name = names.substr(start);
    scoreboard[name] = 0;
}

Which, if you really want to use find() , can be re-written more like this:如果您真的想使用find() ,可以将其重写为:

std::string::size_type start = names.find_first_not_of(' ');
std::string name;

while (start != std::string::npos)
{
    std::string::size_type pos = names.find(' ', start);
    if (pos == std::string::npos)
    {
        name = names.substr(start);
        start = pos;
    }
    else
    {
        name = names.substr(start, pos - start);
        start = names.find_first_not_of(' ', pos + 1);
    }

    scoreboard[name] = 0;
}

However, there is a must easier way to split a string on spaces (and other whitespace characters):但是,必须有一种更简单的方法可以在空格(和其他空白字符)上拆分字符串:

std::istringstream iss(names);
std::string name;

while (iss >> name)
{
    scoreboard[name] = 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何将这个 std::string 转换为 std::basic 字符串? - How would I get convert this std::string into a std::basic string? 我如何在std :: string中随机创建拼写错误? - How would I randomly create typos in a std::string? 我将如何划分这堂课? - How would I separate this class? 如何在1个字节的普通字符串中存储日语字符? - how I'm able to store a japanese character in 1 byte normal string? std :: string运算符[]如何返回引用而不是字符? - How can std::string operator[] return a reference rather than the character? 如何将字符串数组的元素中的多个字符放入 TEXT 中,因为它必须是指向字符 [outtextxy(X, Y, TEXT)] 的指针? - How can I put more than one character from an element of string array inside TEXT as it must ba a pointer to a character [ outtextxy(X , Y, TEXT) ]? 我需要 std::conditional 但有两个以上的选择 - I need std::conditional but with more than two choices 如何在Visual C ++中将std :: bind与4个以上的占位符绑定? - How do I std::bind with more than 4 placeholders in Visual C++? 我该如何转换std :: bitset <N> 到std :: bitset <M> ? - How can I cast an std::bitset<N> to an std::bitset<M>? 在同一个字符串文字中包含 \n 字符是否比在额外的一组“&lt;&lt;”中更有效? - Would it be more efficient to have the \n character in the same string literal than to have an extra set of “<<”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM