walkany 2025-04-02 09:29 采纳率: 100%
浏览 11
已结题

奇怪的C++运行错误,不知道是代码,还是什么错误

期待把字符串按照 & 和 =分割成 map[name] = value这种形式,但是分割错误。result=OkExisted&mac=00:0c:29:7a:e1:5a&time=1709494437应该分割成:result=OkExisted mac=00:0c:29:7a:e1:5a time=1709494437; 错误的结果是其中mac:mac=00:0c:29:7a:e1:5a&time=1709494437
代码:

#include<iostream>
#include<map>
using namespace std;

int get_web_paras(std::string param_list, std::map<std::string, std::string>& m_name_value)
{
    std::string pure_para;
    std::string name, valu;
    std::string one_para;
    size_t start;
    size_t equa_loca;
    if(param_list.find("=") == std::string::npos)
    {
        return 1;
    }

    size_t loca = param_list.find("?");
    if(loca != std::string::npos)
    {
        pure_para = param_list.substr(loca + 1);
    }else {
        pure_para = param_list;
    }
    loca = pure_para.find('&');
    start = 0;
    while(loca != std::string::npos)
    {
//result=OkExisted&mac=00:0c:29:7a:e1:5a&time=1709494437
        one_para = pure_para.substr(start, loca);
        printf("\n%s:%d start=%lu,loca=%lu onePara=%s \n",__func__, __LINE__, start, loca, one_para.c_str());
        equa_loca = one_para.find("=");
        if(equa_loca != std::string::npos)
        {
            name = one_para.substr(0, equa_loca);
            valu = one_para.substr(equa_loca + 1);
            printf("\n%s:%d map[%s]=%s\n",__func__, __LINE__, name.c_str(), valu.c_str());
            m_name_value[name] = valu;
        }
        start = loca + 1;
        loca = pure_para.find("&", start);
        one_para.clear();
    }

    one_para = pure_para.substr(start);
    printf("\n%s:%d start=%lu,loca=%lu onePara=%s \n",__func__, __LINE__, start, loca, one_para.c_str());
    equa_loca = one_para.find("=");
    if(equa_loca != std::string::npos)
    {
        name = one_para.substr(0, equa_loca);
        valu = one_para.substr(equa_loca + 1);
        printf("\n%s:%d map[%s]=%s\n",__func__, __LINE__, name.c_str(), valu.c_str());
        m_name_value[name] = valu;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    std::string paras = "result=OkExisted&mac=00:0c:29:7a:e1:5a&time=1709494437";
    //std::string paras = "mac=00:0c:29:7a:e1:5a&time=1709494437";
    std::map<std::string, std::string> ret_paras;
    get_web_paras(paras, ret_paras);
    for(auto it : ret_paras)
    {
        printf("\nret_para[%s] = %s\n", it.first.c_str(), it.second.c_str());
    }
}

运行结果,


get_web_paras:37 start=0,loca=16 onePara=result=OkExisted

get_web_paras:43 map[result]=OkExisted

get_web_paras:37 start=17,loca=38 onePara=mac=00:0c:29:7a:e1:5a&time=1709494437

get_web_paras:43 map[mac]=00:0c:29:7a:e1:5a&time=1709494437

get_web_paras:52 start=39,loca=18446744073709551615 onePara=time=1709494437

get_web_paras:58 map[time]=1709494437

ret_para[mac] = 00:0c:29:7a:e1:5a&time=1709494437

ret_para[result] = OkExisted

ret_para[time] = 1709494437

  • 写回答

4条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-04-02 09:39
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析:
      - 要将给定的字符串按照&=进行分割,并存储到一个map中。主要难点在于正确处理字符串的解析,确保分割逻辑的准确性以及处理可能出现的格式不一致情况。
    2. 解决方案:
      - 可以使用C++的字符串处理函数来实现分割和解析。以下是一个示例代码:
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <map>
    
    std::map<std::string, std::string> splitString(const std::string& str) {
        std::map<std::string, std::string> result;
        std::istringstream iss(str);
        std::string token;
        while (std::getline(iss, token, '&')) {
            std::istringstream pairIss(token);
            std::string key, value;
            if (std::getline(pairIss, key, '=') && std::getline(pairIss, value)) {
                result[key] = value;
            }
        }
        return result;
    }
    
    • 调用示例:
    int main() {
        std::string str = "result=OkExisted&mac=00:0c:29:7a:e1:5a&time=17094944";
        std::map<std::string, std::string> mapResult = splitString(str);
        for (const auto& pair : mapResult) {
            std::cout << pair.first << " = " << pair.second << std::endl;
        }
        return 0;
    }
    
    1. 多种解决方案及优缺点:
      - 使用strtok函数(C风格)
      • 优点:相对简单直接,是C语言中常用的字符串分割方法。
      • 缺点:不是线程安全的,在多线程环境下可能会出现问题。而且需要手动管理内存,例如在分割过程中创建临时字符串来存储分割后的子串。
      • 示例代码:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void splitStringWithStrtok(const char* str, std::map<std::string, std::string>& result) {
        char* strCopy = strdup(str);
        char* token = strtok(strCopy, "&");
        while (token!= NULL) {
            char* keyValue = strtok(token, "=");
            if (keyValue!= NULL) {
                char* value = strtok(NULL, "");
                if (value!= NULL) {
                    result[keyValue] = value;
                }
            }
            token = strtok(NULL, "&");
        }
        free(strCopy);
    }
    
    • 使用正则表达式(C++ 11及以上)
      • 优点:可以更灵活地处理复杂的字符串匹配和分割需求,对于不同格式的字符串分割有更好的适应性。
      • 缺点:引入了正则表达式库,增加了代码的复杂性和编译时的依赖。
      • 示例代码:
    #include <iostream>
    #include <regex>
    #include <string>
    #include <map>
    
    std::map<std::string, std::string> splitStringWithRegex(const std::string& str) {
        std::map<std::string, std::string> result;
        std::regex pattern(R"((\w+)=([^&]*))");
        std::sregex_iterator it(str.begin(), str.end(), pattern);
        std::sregex_iterator end;
        while (it!= end) {
            std::smatch match = *it;
            result[match.str(1)] = match.str(2);
            ++it;
        }
        return result;
    }
    
    1. 总结:
      - 上述提供了几种常见的分割字符串并存储到map中的方法。使用istringstream的方法相对简洁且易于理解,是比较推荐的方式。在实际应用中,可以根据具体需求和场景选择合适的方法。如果需要处理复杂的字符串格式或多线程环境,正则表达式或更高级的字符串处理库可能更合适。

    通过上述代码示例,可以准确地将给定字符串按照要求分割并存储到map中,实现map[name] = value的形式。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月10日
  • 已采纳回答 4月2日
  • 创建了问题 4月2日