我使用arduino MEGA解析网址的参数部分。 参数的顺序无关紧要。我有以下代码,并使用strtok进行了尝试。
log4j-api-2.11.0.jar
并将拆分
char text[] = "ssid=SSID&pwd=PASSWORD&userId=1234"
并再次将其拆分为键和值
ssid=SSID
pwd=PASSWORD
userId=1234
我尝试使用strtok进行第一次拆分。
ssid
SSID
pwd
PASSWORD
userId
1234
并且输出符合预期:
输出:
char *ptr;
ptr = strtok(params, "&");
while (ptr != NULL) {
Serial.println(urlParam);
ptr = strtok(NULL, "&");
}
然后进行下一个拆分:
ssid=SSID
pwd=PASSWORD
userId=1234
但是输出只是
char *ptr;
ptr = strtok(params, "&");
while (ptr != NULL) {
char *paramKey;
char *paramValue;
paramKey = strtok(ptr, "=");
Serial.println(paramKey);
if (paramKey == 'ssid'){
paramValue = strtok(NULL, "=");
Serial.println(paramValue);
ssidName = paramValue;
}
if (paramKey == 'pwd'){
...
}
if (paramKey == 'userId'){
...
}
ptr = strtok(NULL, "&");
}
看起来循环无法正常工作。
我在哪里犯错? 还有其他解决此字符串的方法吗?
答案 0 :(得分:3)
strtok
函数使用内部静态变量来跟踪其当前状态。当您像使用函数那样对多个不同的子字符串使用该函数时,便会进入内部状态。
您需要使用strtok_r
,它使用一个外部变量来跟踪状态。
char *ptr, *sav1 = NULL;
ptr = strtok_r(params, "&", &sav1); // outer strtok_r, use sav1
while (ptr != NULL) {
char *paramKey;
char *paramValue;
char *sav2 = NULL;
paramKey = strtok_r(ptr, "=", &sav2); // inner strtok_r, use sav2
Serial.println(paramKey);
if (!strcmp(paramKey, "ssid")) {
paramValue = strtok_r(NULL, "=", &sav2); // inner strtok_r, use sav2
Serial.println(paramValue);
ssidName = paramValue;
}
if (!strcmp(paramKey, "pwd")) {
...
}
if (!strcmp(paramKey, "userId")) {
...
}
ptr = strtok_r(NULL, "&", &sav1); // outer strtok_r, use sav1
}
与解析问题无关,您也无法将字符串与==
进行比较。您需要改用strcmp
,字符串常量用双引号而不是单引号引起来。
答案 1 :(得分:1)
您有三个问题:
答案 2 :(得分:0)
#include <stdio.h>
#include <string.h>
struct split_result {
char first_part[64];
char second_part[64];
};
split_result return_left(char splitter, const char *str);
int main() {
/*
ssid=SSID
pwd=PASSWORD
userId=1234
*/
char *str = "ssid=109304905995";
split_result result = return_left('=', str);
printf("first part: %s \n second part: %s\n", result.first_part, result.second_part);
return 0;
}
split_result return_left(char splitter, const char *str) {
int i = 0;
split_result split_ptr;
while (str[i] != 0) {
//we found splitter
if ((char)str[i] == splitter) {
//remove first half
strncpy_s(split_ptr.first_part, str, (int)(&str[i]-str));
break;
}
//we need to remove second half now
i++;
}
strcpy_s(split_ptr.second_part, &str[i+1]);
return split_ptr;
}
我希望这对任何人都有帮助。
答案 3 :(得分:0)
如果输入始终为key=value&...key=value
,则可以遍历字符串并使用strtok
捕获每个键和值。
#include <stdio.h>
#include <string.h>
int main ( void) {
char text[] = "ssid=SSID&pwd=PASSWORD&userId=1234";
char *key = NULL;
char *value = NULL;
char *ssidName = NULL;
char *pwdName = NULL;
char *useridName = NULL;
key = strtok(text, "=");//first key
while ( key) {
printf ( "\nkey %s\n", key);
value = strtok(NULL, "&");//value between = and &
if ( !strcmp ( key, "ssid")) {
if ( value) {
ssidName = value;
printf ( "value %s\n", ssidName);
}
}
if ( !strcmp ( key, "pwd")) {
if ( value) {
pwdName = value;
printf ( "value %s\n", pwdName);
}
}
if ( !strcmp ( key, "userId")) {
if ( value) {
useridName = value;
printf ( "value %s\n", useridName);
}
}
key = strtok(NULL, "=");//next key
}
return 0;
}
请注意,指针*Name
指向text
中的某个位置。如果text
被覆盖,则这些指针将不再指向其先前的值。在这种情况下,请为指针分配内存并复制内容。