You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32/Arduino IDE(C++)中移除字符串控制字符的技术求助

如何在ESP32/Arduino IDE(C++)中移除字符串控制码并格式化输出?

问题描述

我有一个存储在String变量中的字符串,内容如下:

S*⸮

K! NAG 00.10
K" NMAGICSTAR 2 L V1.0-1
K# AUFSTELLORT: S 00000000
K$ GERAET NR.: 0000000000
KC ZULASSUNGS NR.:411107770
K) BAUART: NAG5A02
K( ABLAUFDATUM: 2021/04

需要移除其中的控制码(比如开头的S*⸮,还有每行的K!、K"这类前缀——原字符串中控制码前还有小矩形显示但已被移除),最终得到符合要求的格式:每行最长24字符,以LF [0Ah]结尾。另外参考文档说明:控制码ESC 'S' 21h LF是带厂商码、机器码和数据集码的XON起始序列,也需要处理掉。

求在ESP32/Arduino IDE(C++)中的具体实现方法。


解决方案

在Arduino/ESP32环境下,我们可以通过逐行解析、过滤前缀和控制序列的方式来实现需求,下面是完整的代码示例和步骤说明:

核心思路

  1. 先去除开头的无效控制序列(比如S*⸮这类),定位到有效内容的起始行(两条分隔线之间的部分);
  2. 逐行遍历有效内容,移除每行开头的K+特殊字符的控制前缀;
  3. 确保每行长度不超过24字符,若超过可按需截断(或根据业务逻辑调整);
  4. 统一用LF(\n)作为行结尾,组装最终的结果字符串。

代码实现

String processRawData(String rawStr) {
  String result = "";
  // 第一步:定位有效内容区域(两条分隔线之间的部分)
  int firstSeparator = rawStr.indexOf("------------------------");
  int secondSeparator = rawStr.indexOf("------------------------", firstSeparator + 1);
  
  if (firstSeparator == -1 || secondSeparator == -1) {
    // 未找到分隔线,返回空或原始字符串(根据需求调整)
    return "";
  }
  
  // 截取两条分隔线之间的内容
  String content = rawStr.substring(firstSeparator + 24, secondSeparator);
  
  // 第二步:按行分割内容
  int startPos = 0;
  while (startPos < content.length()) {
    int endPos = content.indexOf('\n', startPos);
    if (endPos == -1) {
      endPos = content.length();
    }
    String line = content.substring(startPos, endPos);
    line.trim(); // 去除行首尾的空白字符
    
    // 第三步:移除K开头的控制前缀(匹配K后跟任意非字母数字字符的前缀)
    if (line.startsWith("K")) {
      // 找到第一个空格的位置,截取空格后的内容
      int spacePos = line.indexOf(' ');
      if (spacePos != -1) {
        line = line.substring(spacePos + 1);
      } else {
        // 若没有空格,说明该行无效,跳过
        startPos = endPos + 1;
        continue;
      }
    }
    
    // 第四步:确保每行不超过24字符,超过则截断
    if (line.length() > 24) {
      line = line.substring(0, 24);
    }
    
    // 添加LF结尾,加入结果
    result += line + "\n";
    
    startPos = endPos + 1;
  }
  
  return result;
}

// 使用示例
void setup() {
  Serial.begin(115200);
  String rawData = "S*⸮\n------------------------\nK! NAG 00.10\nK\" NMAGICSTAR 2 L V1.0-1\nK# AUFSTELLORT: S 00000000\nK$ GERAET NR.: 0000000000\nKC ZULASSUNGS NR.:411107770\nK) BAUART: NAG5A02\nK( ABLAUFDATUM: 2021/04\n------------------------";
  
  String processed = processRawData(rawData);
  Serial.println("处理后结果:");
  Serial.println(processed);
}

void loop() {
  // 空循环
}

代码说明

  • 分隔线定位:通过查找两条------------------------分隔线,精准提取中间的有效数据行,避免处理开头的控制序列;
  • 行分割与前缀过滤:逐行处理时,判断是否以K开头,找到第一个空格后截取后续内容,移除控制前缀;
  • 长度控制:对每行内容进行截断,确保不超过24字符;
  • 换行处理:统一添加LF(\n)作为行结尾,符合需求格式。

如果原始字符串中的控制码前缀(比如K!、K")的格式有变化(比如没有空格),可以调整前缀匹配的逻辑,比如通过正则表达式(Arduino中可使用Regexp库)来更灵活匹配,但上面的基础实现已经能覆盖当前给出的示例场景。


内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:46:37