Arduino环境下如何从混合字符数组中提取时间整数
解决从固定格式字符串提取时间并转为整数数组的问题
问题分析
你需要从格式为"YYYY-MM-DDTHH:MM:SS>YYYY-MM-DDTHH:MM:SS"的字符数组中提取HH:MM:SS部分,并将其转为092703这类整数存入数组。
当前代码的核心问题是**strtok嵌套调用会破坏其内部状态**:strtok依赖全局静态变量记录分割位置,内层调用会覆盖这个状态,导致外层分割逻辑混乱,输出不符合预期。同时你在外层循环中错误地将分隔符设为空格,而非>,也会导致分割错误。
解决方案一:利用固定格式直接提取(推荐)
由于输入格式固定,每个时间片段都是T后紧跟HH:MM:SS,可以直接用strchr定位T的位置,提取后续时间字符串后通过sscanf解析为时分秒,再组合成整数。
示例代码
#include <stdio.h> #include <string.h> void setup() { Serial.begin(115200); Serial.println("Hello, ESP32-S2!"); char str[] = "2018-09-20T09:27:03>2023-09-20T13:03:33"; int time_arr[2]; // 存储转换后的时间整数 int idx = 0; // 用">"分割出两个时间片段 char *pch = strtok(str, ">"); while (pch != NULL && idx < 2) { // 定位当前片段中的'T'字符 char *t_pos = strchr(pch, 'T'); if (t_pos != NULL) { int hh, mm, ss; // 从T的下一位开始解析时分秒 if (sscanf(t_pos + 1, "%d:%d:%d", &hh, &mm, &ss) == 3) { // 组合为HHMMSS格式的整数 time_arr[idx++] = hh * 10000 + mm * 100 + ss; Serial.printf("提取到时间:%02d:%02d:%02d → 整数:%06d\n", hh, mm, ss, time_arr[idx-1]); } } pch = strtok(NULL, ">"); } // 输出最终整数数组 Serial.println("\n最终整数数组:"); for (int i = 0; i < idx; i++) { Serial.printf("%06d\n", time_arr[i]); } } void loop() { delay(10); }
代码说明
strchr定位时间起始点:跳过前面的日期部分,直接定位到T,后续就是目标时间字符串。sscanf解析时间:按%d:%d:%d格式读取时分秒,确保解析准确性。- 整数组合:将时分秒转为
HHMMSS格式的整数,用%06d格式化输出可保留前导零。
解决方案二:避免strtok嵌套调用
如果坚持使用strtok,可以先将所有>分割的片段保存到数组,再逐个处理每个片段的时间部分,避免嵌套调用破坏strtok的内部状态。
示例代码
#include <stdio.h> #include <string.h> void setup() { Serial.begin(115200); Serial.println("Hello, ESP32-S2!"); char str[] = "2018-09-20T09:27:03>2023-09-20T13:03:33"; char *segments[2]; // 存储分割后的时间片段 int seg_idx = 0; int time_arr[2]; int time_idx = 0; // 第一步:分割出所有时间片段 char *pch = strtok(str, ">"); while (pch != NULL && seg_idx < 2) { segments[seg_idx++] = pch; pch = strtok(NULL, ">"); } // 第二步:逐个处理片段提取时间 for (int i = 0; i < seg_idx; i++) { char temp[20]; strcpy(temp, segments[i]); // 复制到临时变量,避免修改原字符串 char *sub_pch = strtok(temp, "T"); while (sub_pch != NULL) { // 通过是否包含':'判断是否为时间部分 if (strchr(sub_pch, ':') != NULL) { int hh, mm, ss; sscanf(sub_pch, "%d:%d:%d", &hh, &mm, &ss); time_arr[time_idx++] = hh * 10000 + mm * 100 + ss; Serial.printf("提取到时间:%s → 整数:%06d\n", sub_pch, time_arr[time_idx-1]); } sub_pch = strtok(NULL, "T"); } } // 输出最终数组 Serial.println("\n最终整数数组:"); for (int i = 0; i < time_idx; i++) { Serial.printf("%06d\n", time_arr[i]); } } void loop() { delay(10); }
代码说明
- 先保存所有片段:避免嵌套调用
strtok时覆盖状态,确保每个片段独立处理。 - 临时字符串处理:复制片段到临时变量再分割,防止修改原字符串影响后续逻辑。
- 时间判断逻辑:通过
:字符区分日期和时间部分,精准提取目标内容。
输出结果
两种方案最终都会输出:
Hello, ESP32-S2! 提取到时间:09:27:03 → 整数:092703 提取到时间:13:03:33 → 整数:130333 最终整数数组: 092703 130333
内容的提问来源于stack exchange,提问作者Alt
相关产品推荐
相关产品推荐

