在<key, value>c++的基础上将String内容存入map

Storing String content in map on the basis of <key, value> c++

我有一个字符串“parrot -color green -peak”。我想用 格式将这个字符串存储在地图中。其中第一个字符串被视为二进制可执行对象,其余值应以 map 格式存储,其中(-string 表示键)紧接着的下一个字符串被视为该特定键的值。如果该值为空,则应存储为空字符串。但是从我的代码来看,它把键存储为值。还请检查提到的预期输出和从现有代码观察到的结果,以便更好地理解。提前致谢。

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

using namespace std;

int main() {
    // your code goes here
    string s = "parrot -color green -peak";
    char sep = '-';
    map<string, string> clArgs;
    
    // find first '-' and copy contents
    string executable_name = s.substr(0, s.find_first_of(sep));
    cout << "exec name = " << executable_name << endl;
    
    s.erase(0, s.find_first_of(sep));
    cout << "s = " << s << endl;
    
    // iterate over string and copy key-value pairs
    int pos;
    while ((pos = s.find_first_of(sep, 1)) != string::npos)
    {
        string keyVal = s.substr(0, pos);
        s = s.substr(pos);
        
        string key, value;
        key = keyVal.substr(0, keyVal.find_first_of(' '));
        keyVal = keyVal.substr(keyVal.find_first_of(' ')+1);
        value = keyVal.substr(0, keyVal.find_first_of(' '));
        clArgs[key] = value;
    }
    
    if (s.length() != 0)
    {
        // there is still last command line arg remaining
        // need to process it as well
        clArgs[s.substr(0, s.find_first_of(' '))] = s.substr(s.find_first_of(' ')+1);
    }
    
    cout << "Printing key-value pairs ...\n";
    for (map<string, string>::iterator it = clArgs.begin(); it != clArgs.end(); it++)
    {
        cout << "(key = " << it->first << ", value = " << it->second << ")\n";
    }
    return 0;
}
output from above code:-

exec name = parrot 
s = -color green -peak
Printing key-value pairs ...
(key = -color, value = green)
(key = -peak, value = -peak)

expected output:-

exec name = parrot 
s = -color green -peak
Printing key-value pairs ...
(key = -color, value = green)
(key = -peak, value = )
  1. 如果参数字符串是可选的,那么我建议您将输入解析为令牌,然后逐个处理令牌。
  2. 您当前假设 key/value 对的值始终存在。搜索 space 字符后不检查值是否存在。
key = keyVal.substr(0, keyVal.find_first_of(' '));
keyVal = keyVal.substr(keyVal.find_first_of(' ')+1);
value = keyVal.substr(0, keyVal.find_first_of(' '));

s 是第二次迭代的“-peak”。 keyVal.find_first_of(' ')npos 并且通过 keyVal.find_first_of(' ')+1 访问字符不是您所期望的。您应该在递增之前检查它是否 npos

auto space = keyVal.find_first_of(' ');
key = keyVal.substr(0, space);
if (space != keyVal.npos) {
  keyVal = keyVal.substr(space + 1);
  value = keyVal.substr(0, keyVal.find_first_of(' '));
} else {
  keyVal = "";
  value = "";
}

您的代码相当复杂,可以从使用 std::stringstreamstd::getline 中获益。字符串函数很容易传递无效索引。我建议您使用调试器来查找您的期望值在哪里。使用 getline 和流拆分字符串很简单。稍微简单一点的版本可能是这样的:

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

using namespace std;

int main() {
    string s = "parrot -color green -peak";
    char sep = '-';
    map<string, string> clArgs;

    // extract first word
    std::stringstream ss{s};    
    std::string exec_name;
    std::getline(ss,exec_name,sep);
    
    // extract portions of the string separated by -
    std::string key_value_pair;
    while (std::getline(ss,key_value_pair,sep)) {
        // now extract first and second word 
        std::stringstream skvp{key_value_pair};
        std::string key;
        std::string value;
        skvp >> key >> value;
        clArgs[key] = value;
    }

    std::cout << exec_name << "\n";
    
    cout << "Printing key-value pairs ...\n";
    for (const auto& e : clArgs)
    {
        cout << "(key = " << e.first << ", value = " << e.second << ")\n";
    }
}

Output:

parrot 
Printing key-value pairs ...
(key = color, value = green)
(key = peak, value = )