0

问题:我是 C++ 新手,在编写了以下代码之后,似乎应该有一种方法可以缩短它。也许通过某种方式匹配字符串?这将如何完成?

该函数message接受通过串行端口接收的字符串,并pinValues[]根据message. 将设置的值由最后一个字符H或.L\n

字符串模式:(a number)(H or L)\n

例如:message == "4H\n"将第 5 个元素设置pinValues[4]HIGH. 字符串开头的数字可以是1 到 2 位数字

void setPinValues(String message) {
     if( message == "1H\n" ) {
          pinValues[1] = HIGH;
      }
      if( message == "1L\n" ) {
          pinValues[1] = LOW;
      }
      if( message == "2H\n" ) {
          pinValues[2] = HIGH;
      }
      if( message == "2L\n" ) {
          pinValues[2] = LOW;
      }
      if( message == "3H\n" ) {
          pinValues[3] = HIGH;
      }
      if( message == "3L\n" ) {
          pinValues[3] = LOW;
      }
      if( message == "4H\n" ) {
          pinValues[4] = HIGH;
      }
      if( message == "4L\n" ) {
          pinValues[4] = LOW;
      }
      if( message == "5H\n" ) {
          pinValues[5] = HIGH;
      }
      if( message == "5L\n" ) {
          pinValues[5] = LOW;
      }
      if( message == "6H\n" ) {
          pinValues[6] = HIGH;
      }
      if( message == "6L\n" ) {
          pinValues[6] = LOW;
      }
}
4

3 回答 3

0

在从前两个字符中提取键和值时,我会对字符串进行一些完整性检查。如果您不需要对消息进行全面检查,则它可以短至

void setPinValues(String message) {
    pinValues[ message[0] - '0' ] = (message[1] == 'H') ? HIGH:LOW;
}

尽管您可能希望将其延长一点,即检查字符串长度,并且您检查的 2 个字符在正确的范围内。IE

void setPinValues(string message) {

  if ( 
      message.size() >= 2 
      and 
      message[0] >= '1' and message[0] <= '6' 
      and (message[1]=='H' or message[1]=='L')
       ) {
    pinValues[ message[0] - '0' ] = (message[1] == 'H') ? HIGH:LOW;
  }
}

编辑:您还可以将其扩展到检查两个前导数字,即

int n, off=0;


if ( s[off] <= '9' and s[off] >= '0') 
{
  n = s[off++] - '0';
}
if ( s[off] <= '9' and s[off] >= '0')  
{
  n = 10*n + s[off++] - '0';
}
if (off > 0 and (s[1]=='H' or s[1]=='L')) {
  pinValues[ message[0] - '0' ] = (message[1] == 'H') ? HIGH:LOW;
}
于 2013-09-21T01:54:12.543 回答
0

假设String实际上是一个std::string或具有相同的接口,并且还假设一个 ASCII 兼容的字符集......

void setPinValues(String message) {
    const size_t sz = message.size();

    // input validation, ignore the message if it doesn't fit the pattern
    // you can remove this "if" block if the message has already been validated
    if (   (sz < 3) || (sz > 4)
           // note how message[0] will be checked twice if sz == 3
           // once as message[0] and once as message[sz -3]
           // but if sz == 4 we check message[0] and message[1]
        || (message[0] < '0') || (message[0] > '9')
        || (message[sz - 3] < '0') || (message[sz - 3] > '9')
        || ((message[sz - 2] != 'H') && (message[sz - 2] != 'L'))
        || (message[sz - 1] != '\n'))
      return;

    // convert the first or two characters to a number
    int pinNumber = message[0] - '0';
    if (sz == 4)
        pinNumber = (pinNumber * 10) + (message[1] - '0');

    // additional check to verify the pin number is in the correct range
    if ((pinNumber < 1) || (pinNumber > 6))
        return;

    // apply
    pinValues[pinNumber] = (message[sz - 2] == 'H' ? HIGH : LOW);
}
于 2013-09-21T01:54:53.790 回答
0

这可能不是官方“C++”认可的方式,但你可以这样做:

unsigned int pinNo = 0;
unsigned char level = 0;
int result = sscanf(message.c_str(), "%u%c", &pinNo, &level);
if (result < 2)
  // it failed
if (pinNo > 6)
  // bad data
levelVal = (level == 'H') ? HIGH : LOW;
于 2013-09-21T02:03:43.250 回答