简体   繁体   English

字符串解析以在 C++ 中为 Arduino 提取 int

[英]String parsing to extract int in C++ for Arduino

I'm trying to write a sketch that allows a user to access data in EEPROM using the serial monitor.我正在尝试编写一个草图,允许用户使用串行监视器访问 EEPROM 中的数据。 In the serial monitor the user should be able to type one of two commands: “read” and “write.在串行监视器中,用户应该能够键入以下两个命令之一:“读取”和“写入”。 "Read" should take one argument, an EEPROM address. “读取”应采用一个参数,即 EEPROM 地址。 "Write" should take two arguments, an EEPROM address and a value. “Write”应该有两个参数,一个 EEPROM 地址和一个值。 For example, if the user types “read 7” then the contents of EEPROM address 7 should be printed to the serial monitor.例如,如果用户键入“read 7”,则 EEPROM 地址 7 的内容应打印到串行监视器。 If the user types “write 7 12” then the value 12 should be written into address 7 of the EEPROM.如果用户键入“write 7 12”,则值 12 应写入 EEPROM 的地址 7。 Any help is much appreciated.任何帮助深表感谢。 I'm not an expert in Arudino, still learning ;).我不是 Arudino 的专家,仍在学习 ;)。 In the code below I defined inByte to be the serail.read().在下面的代码中,我将 inByte 定义为 serail.read()。 Now how do I extract numbers from the string "inByte" to assign to "val" and "addr"现在如何从字符串“inByte”中提取数字以分配给“val”和“addr”

void loop() {

String inByte;
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
  }
  if (inByte.startsWith("Write")) {
    EEPROM.write(addr, val);
  }
   if (inByte.startsWith("Read")) {
   val= EEPROM.read(addr);
  }

  delay(500);
}

Serial.read() only reads a single character. Serial.read()只读取一个字符。 You should loop until no more input while filling your buffer or use a blocking function like Serial.readStringUntil() or Serial.readBytes() to fill a buffer for you.您应该循环直到在填充缓冲区时不再有输入为止,或者使用像Serial.readStringUntil()Serial.readBytes()类的阻塞函数为您填充缓冲区。

https://www.arduino.cc/en/Serial/ReadStringUntil https://www.arduino.cc/en/Serial/ReadStringUntil

https://www.arduino.cc/en/Serial/ReadBytes https://www.arduino.cc/en/Serial/ReadBytes

Or you can use Serial.parseInt() twice to grab the two values directly into a pair of integers.或者您可以使用Serial.parseInt()两次将两个值直接抓取为一对整数。 This function will skip the non numerical text and grab the values.此函数将跳过非数字文本并获取值。 This method is also blocking.这个方法也是阻塞的。 https://www.arduino.cc/en/Reference/StreamParseInt A patch I wrote to improve this function is available in the latest hourly build, but the old versions still work fine for simple numbers with the previous IDE's https://www.arduino.cc/en/Reference/StreamParseInt我为改进此功能而编写的补丁在最新的每小时版本中可用,但旧版本对于使用以前 IDE 的简单数字仍然可以正常工作

The blocking methods can be tweaked using Serial.setTimeout() to change how long they wait for input (1000ms default) https://www.arduino.cc/en/Serial/SetTimeout可以使用Serial.setTimeout()调整阻塞方法以更改等待输入的时间(默认为 1000 毫秒) https://www.arduino.cc/en/Serial/SetTimeout

[missed the other answer, there's half my answer gone] [错过了另一个答案,我的答案已经消失了一半]

I was going to say use Serial.readStringUntil('\\n') in order to read a line at a time.我打算说使用Serial.readStringUntil('\\n')以便一次读取一行。

To address the part:要解决该部分:

how do I extract numbers from the string "inByte" to assign to "val" and "addr"如何从字符串“inByte”中提取数字以分配给“val”和“addr”

This is less trivial than it might seem and a lot of things can go wrong.这不像看起来那么琐碎,很多事情都可能出错。 For simplicity, let's assume the input string is always in the format /^(Read|Write) (\\d+)( \\d+)?$/ .为简单起见,我们假设输入字符串的格式始终为/^(Read|Write) (\\d+)( \\d+)?$/

A simple way to parse it would be to find the spaces, isolate the number strings and call .toInt() .解析它的一种简单方法是找到空格,隔离数字字符串并调用.toInt()

...
int val, addr;

int addrStart = 0;
while(inByte[addrStart] != ' ' && addrStart < inByte.length())
  addrStart++;
addrStart++; //skip the space

int addrEnd = addrStart + 1;
while(inByte[addrEnd] != ' ' && addrEnd < inByte.length())
  addrEnd++;

String addrStr = inByte.substring(addrStart, addrEnd); //excludes addrEnd
addr = addrStr.toInt();

if (inByte.startsWith("Write")) {
  int valEnd = addrEnd+1;

  while(inByte[varEnd] != ' ' && varEnd < inByte.length())
      valEnd++;

  String valStr = inByte.substring(addrEnd+1, valEnd);
  val = valStr.toInt();

  EEPROM.write(addr, val);
}
else if (inByte.startsWith("Read")) {
 val = EEPROM.read(addr);
}

This can fail in all sorts of horrible ways if the input string has a double space or the numbers are malformed, or has any other subtle error.如果输入字符串有双空格或数字格式错误,或者有任何其他细微错误,这可能会以各种可怕的方式失败。

If you're concerned with correctness, I suggest you look into a regex library, or even an standard format such as JSON - see ArduinoJson .如果您关心正确性,我建议您查看正则表达式库,甚至是 JSON 等标准格式 - 请参阅ArduinoJson

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM