在C ++中拆分字符串

时间:2016-07-30 12:05:10

标签: c++ split scanf esp8266 arduino-ide

我想要的:

解析MAC地址字符串并获取六个uint8_t值的数组,输入类似 string str = "01:23:45:AB:CD:EF";

我尝试了什么(并且没有工作):

sscanf(str.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);

为什么它不起作用:我正在使用Arduino IDE为ESP8266 Wi-Fi模块编程。尽管Arduino板的官方内核支持sscanf(),但ESP8266的内核却不支持sscanf。 (The solution to the issue given on GitHub不起作用,如 nicjohnston 所述。)

最不重要:

任何占用过多RAM,CPU周期或程序存储的东西。
还有一些东西使用或直接/间接取决于setjmplongjmpfor(uint8_t i=0; i<5; i++) mac[i]=strtol(Serial.readStringUntil(':').c_str(),NULL,16); mac[6]=strtol(Serial.readStringUntil('\n').c_str(),NULL,16); ,(和其他几个)可能不起作用。

修改 @ m.s的回答。下面是绝对正确的,但我意识到在我设计了自己的代码之后(见下文)。

http://domain.com/blog/contact

3 个答案:

答案 0 :(得分:2)

您可以使用正则表达式提取内容并存储在数组中。然后解析数组以获得相应的uint8_t等价物。

正则表达式可能类似于:[0-9A-F][0-9A-F]

您可以参考此参考链接,了解有关正则表达式及其使用方法的更多详细信息:http://www.cplusplus.com/reference/regex/regex_search/

在C ++中,regex_search允许搜索正则表达式模式,并可能提取搜索(或匹配)模式。

答案 1 :(得分:1)

在您的特定用例中,您可以简单地遍历字符串并将十六进制子字符串转换为如下数字:

  • 每个子字符串恰好包含两个十六进制字符;让子串由XY
  • 表示
  • XY位于[0-9]内或[A-F]A 表示 10,{ {1}}表示B等(十进制)
  • 从ASCII值到其中一个字符的数字含义的转换取决于char来自哪个字符集:

  • 如果char 11来自c,则其小数含义为[0-9],即减去偏移量,以便以下映射适用c-'0'

  • 如果字符'0'=>0, '1' => 1, ...来自c,则映射可以表示为[A-F]

  • 然后计算每个子字符串c-'A'+10的数字小数值v,如下所示:XY

  • 子字符串由一个字符分隔(此处为v=X*16 + Y,但这无关紧要)

以下代码实现了这些想法:

:

答案 2 :(得分:0)

我太迟了,而且我的回答是正确的。

我的答案有点不同,因为它使用从一串字符计算十六进制,并使其更多c ++ 11。 虽然我不确定ESP8266模块是否支持它,但我希望它有所帮助。

#include <string>
#include <array>

std::array< uint8_t, 6> MAC_fromStringToArray(const std::string& str)
{
    std::array< uint8_t, 6> ret ;

    for (auto i = 0; i < 6; i++)
    {
        ret[i] = std::stoi(str.substr((i * 3), 2), nullptr, 16);
    }

    return ret;
}

int main()
{
    std::string str = "01:23:45:AB:CD:EF";

    std::array< uint8_t, 6> mac = MAC_fromStringToArray(str);

    return 0;
}

编辑:由于似乎没有可用,我将其改为传统阵列。

uint8_t * MAC_fromStringToArray(const std::string& str, uint8_t arr[])
{
    for (int i = 0; i < 6; i++)
    {
        arr[i] = std::stoi(str.substr((i * 3), 2), nullptr, 16);
    }

    return arr;
}

需要以不同方式调用:

uint8_t arr[6]; 

MAC_fromStringToArray(str, arr);

希望它有所帮助,我担心如果不能访问与您相同的编译器,则很难解决您的情况。