在C++中拆分字符串
Splitting String in C++
我想要什么:
解析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的核心不支持。(正如nicjohnston所说,GitHub上给出的问题解决方案不起作用。)
最不优选:
任何占用过多RAM、CPU周期或程序存储的东西
此外,一些使用或直接/间接依赖于sscanf
、setjmp
、longjmp
(以及其他一些)的东西可能不起作用。
编辑:下面@m.s.的答案是绝对正确的,但在我设计了自己的代码(下面给出)后,我意识到了这一点。
for(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);
在您的特定用例中,您可以简单地迭代字符串并将十六进制子字符串转换为如下数字:
- 每个子字符串恰好由两个十六进制字符组成;设一个子串用
XY
表示 X
和Y
在[0-9]
内或在[A-F]
内,其中A
表示10
,B
表示11
等(十进制)-
从ASCII值到其中一个字符的数字含义的转换取决于字符来自哪个字符集:
-
如果字符
c
来自[0-9]
,则其十进制含义为c-'0'
,即减去偏移量,以便以下映射应用'0'=>0, '1' => 1, ...
-
如果字符
c
来自[A-F]
,则映射可以表示为c-'A'+10
-
每个子串
XY
的数字十进制值v
计算如下:v=X*16 + Y
- 子字符串由一个字符分隔(这里是
:
,但这无关紧要)
以下代码实现了这些想法:
#include <string>
#include <cstdlib>
std::uint8_t getNum(char hexChar)
{
if(hexChar >= '0' && hexChar <= '9')
{
return hexChar - '0';
}
return (hexChar-'A'+10);
}
int main()
{
std::uint8_t mac[6];
std::string str = "01:23:45:AB:CD:EF";
std::uint8_t j = 0;
for(std::uint8_t i = 0; i<6; ++i)
{
mac[i] = getNum(str[j])*16 + getNum(str[j+1]);
j+=3; // get to the next substring
}
}
您可以使用正则表达式提取内容并存储在数组中。然后解析该数组以获得相应的uint8_t
等价物。
正则表达式可能类似于:[0-9A-F][0-9A-F]
有关regex以及如何使用它的更多详细信息,您可以参考此参考链接:http://www.cplusplus.com/reference/regex/regex_search/
在C++中,regex_search
允许搜索正则表达式模式,并可能提取搜索到的(或匹配的)模式。
我来晚了,m.s.的回答是正确的。
我的答案有点不同,因为它使用从字符串中计算十六进制,并使其更像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);
希望它能有所帮助,我担心如果没有和你一样的编译器,很难解决你的问题。
- 将字符串拆分为标记,并将标记拆分为两个单独的数组
- 将字符串拆分为等长 c++ 的部分
- 如何使用 Boost C++ 打印第 n 个字符串拆分?
- 我在将字符串拆分为向量时遇到困难
- C++ 如何将字符串拆分为单个字符
- 是否有用于执行反向字符串拆分器的开箱即用功能?
- 如何将字符串拆分为一组 3 个字符,它们之间有空格
- 将字符串拆分为单个单词并将它们放置在向量中
- 基于其中的数字子字符串拆分字符串
- 如何在C++中将数字字符串拆分为数组
- 如何在 c++ 中将字符串拆分为字符串 2d 数组数组
- 如何将标准::字符串拆分为标准::string_views的范围 (v3)
- 将特定格式的字符串拆分为浮点数和字符串
- 在 c++ 中将字符串拆分为单独的变量
- 用C 中的4个字符将字符串拆分
- 如何用Arduino中的另一个字符串将字符串拆分
- 如何在 Main 方法之外将字符串拆分为标记
- C 将字符串按空白空间将字符串拆分,除非将其封闭在引号中并存储在向量中
- 将字符串拆分为矢量 C++
- 试图将字符串拆分为两个整数