преобразование последовательного сообщения, разделенного запятыми, в 7 переменных без знака Long

Работаю над проектом, где я получаю входные данные, состоящие из строки, разделенной запятыми, например:

"255,10000000,42949672950254,12,22".

а затем числа (без запятых) будут разделены на 6 длинных переменных нравится

var1 = 255
var2 = 10000000
...

Мне нужна была такая функция:

void extractIntegersFromString(String str, int& integer1, int& integer2, int& integer3, int& integer4, int& integer5, int& integer6, int& integer7) {
  int count = 0;
  String temp = "";

  for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);

    if (c == ',') {
      if (count == 0)
        integer1 = String(temp).toInt();
      else if (count == 1)
        integer2 = String(temp).toInt();
      else if (count == 2)
        integer3 = String(temp).toInt();
      else if (count == 3)
        integer4 = String(temp).toInt();
      else if (count == 4)
        integer5 = String(temp).toInt();
      else if (count == 5)
        integer6 = String(temp).toInt();
      else if (count == 6)
        integer7 = String(temp).toInt();

      count++;
      temp = "";
    } else if (c >= '0' && c <= '9') {
      temp += c;
    }
  }

  // Store the last integer if the string doesn't end with a comma
  if (temp != "") {
    if (count == 0)
      integer1 = String(temp).toInt();
    else if (count == 1)
      integer2 = String(temp).toInt();
    else if (count == 2)
      integer3 = String(temp).toInt();
    else if (count == 3)
      integer4 = String(temp).toInt();
    else if (count == 4)
      integer5 = String(temp).toInt();
    else if (count == 5)
      integer6 = String(temp).toInt();
    else if (count == 6)
      integer7 = String(temp).toInt();
  }
}

Эта функция работает с целыми числами, но мне нужен длинный размер большего размера.

PS Я пробовал функцию atol() (и подобные ей), но она не сработала...

, 👍1


2 ответа


0

String.toInt фактически возвращает long. Смотрите код:

long String::toInt(void) const
{
    if (buffer) return atol(buffer);
    return 0;
}

Я пробовал функцию atol() (и подобные ей), но это не сработало

Пожалуйста, опубликуйте свою «попытку», а не просто говорите, что вы это сделали. Возможно, вы сделали это неправильно.


Повторите всю свою технику: существует функция strtok, специально разработанная для разбиения строки на подстроки. в разделителе. Вы могли бы использовать это вместо того, чтобы изобретать велосипед.

Однако это не решает вашу конкретную проблему преобразования подстрок в длинные.

,

Это немного долго; как бы я включил это сюда?, @Lamb Sauce

«Это немного длинно; как бы я включил это сюда?» ... Если кто-то спрашивает что-то в комментариях, ответ (практически для любого из десятков веб-сайтов stackexchange) — отредактировать вопрос и сделать его лучше. ., @st2000

Отредактируйте свой вопрос и покажите примерно полдюжины строк кода, в которых вы использовали функцию atol(). Также покажите результаты. «Не сработало» — значит расплывчато понимать, что это может означать что угодно. Он не скомпилировался? Если бы он скомпилировал, какие результаты вы получили? Покажите цифры. Не говорите «это не сработало»., @Nick Gammon


2

Прежде всего стоит отметить, что третье число в вашем примере сообщение (100000000000, т.е. 1011) слишком велико, чтобы поместиться в длинный без знака. На Arduinoх на базе AVR и большинстве не64-разрядных платформ unsigned long имеет ширину 32 бита и может содержать только числа до 4294967295 (около 4,3×109). Я не знаю простого способа разобрать такое большое количество на AVR.

При этом для анализа такой строки в unsigned long числа, я бы рекомендовал функцию strtoul(). В сравнении в atol(), его преимущество состоит в том, что он сообщает вам, где находится это число. чтение завершено, и вы будете знать, где искать следующее: это сэкономит вам время вызов strchr(). Это также позволяет выполнять некоторую проверку ошибок, чтобы вы знали соответствует ли сообщение ожидаемому формату.

Вот примерная реализация:

/*
 * Parse up to `count` numeric values from `message`,
 * which must be in comma-separated-values format.
 *
 * Return the number of values successfully parsed.
 */
int parse_message(const char *message,
                  unsigned long *values, int count) {
    for (int i = 0; i < count; i++) {
        char *end;  // указатель на следующую нецифру
        values[i] = strtoul(message, &end, 10);
        if (end == message) return i;  // парсинг не удался
        if (*end == ',') end++;        // пропускаем запятую
        message = end;                 // переход к следующему полю
    }
    return count;
}

И небольшой тестовый скетч:

void setup() {
    Serial.begin(9600);

    unsigned long values[7];
    int count = parse_message("255,10000000,100000000000,0,255,12,22",
            values, 7);
    Serial.print(count);
    Serial.println(" numbers successfully parsed:");
    for (int i = 0; i < count; i++)
        Serial.println(values[i]);
}

void loop() {}
,

Спасибо за ваш ответ, я проверю его и приму ответ для дальнейшего использования! :), @Lamb Sauce