Saltar al contenido

¿Cómo divido una entrada string?

Elías, parte de este staff, nos ha hecho el favor de escribir este enunciado ya que conoce a la perfección este tema.

Solución:

Al contrario de otras respuestas, prefiero alejarme de String por las siguientes razones:

  • uso de memoria dinámica (que puede conducir rápidamente a fragmentación del montón y agotamiento de la memoria)
  • bastante lento debido a operadores de construcción / destrucción / asignación

En un entorno integrado como Arduino (incluso para un Mega que tiene más SRAM), prefiero usar funciones C estándar:

  • strchr(): busca un personaje en una C string (es decir char *)
  • strtok(): divide una C string en subcadenas, basadas en un carácter separador
  • atoi(): convierte una C string a una int

Eso conduciría a la siguiente muestra de código:

// Calculate based on max input size expected for one command
#define INPUT_SIZE 30
...

// Get next command from Serial (add 1 for final 0)
char input[INPUT_SIZE + 1];
byte size = Serial.readBytes(input, INPUT_SIZE);
// Add the final 0 to end the C string
input[size] = 0;

// Read each command pair 
char* command = strtok(input, "&");
while (command != 0)

    // Split the command in two values
    char* separator = strchr(command, ':');
    if (separator != 0)
    
        // Actually split the string in 2: replace ':' with 0
        *separator = 0;
        int servoId = atoi(command);
        ++separator;
        int position = atoi(separator);

        // Do something with servoId and position
    
    // Find the next command in input string
    command = strtok(0, "&");

La ventaja aquí es que no tiene lugar ninguna asignación de memoria dinámica; incluso puedes declarar input como una variable local dentro de una función que leería los comandos y los ejecutaría; una vez que se devuelve la función el tamaño ocupado por input (en la pila) se recupera.

Esta función se puede utilizar para separar un string en pedazos basados ​​en cuál es el carácter separador.

String xval = getValue(myString, ':', 0);
String yval = getValue(myString, ':', 1);

Serial.println("Y:" + yval);
Serial.print("X:" + xval);

Convertir String en int

int xvalue = xvalue.toInt(xval);
int yvalue = yvalue.toInt(yval);

Este fragmento de código toma un string y lo separa según un carácter dado y devuelve El elemento entre el carácter de separación

String getValue(String data, char separator, int index)

    int found = 0;
    int strIndex[] =  0, -1 ;
    int maxIndex = data.length() - 1;

    for (int i = 0; i <= maxIndex && found <= index; i++) 
        if (data.charAt(i) == separator 
    return found > index ? data.substring(strIndex[0], strIndex[1]) : "";

Puede hacer algo como lo siguiente, pero tenga en cuenta varias cosas:

Si utiliza readStringUntil(), esperará hasta que reciba el carácter o los tiempos de espera. Así, con tu actual string, la última posición durará un poco más, ya que hay que esperar. Puede agregar un final & para evitar este tiempo de espera. Puede comprobar fácilmente este comportamiento en su monitor, intente enviar el string con y sin extra & y verá ese retraso en el tiempo de espera.

En realidad, no necesita el índice de servo, solo puede enviar su string de posiciones, y obtenga el índice de servo por la posición del valor en el string, algo como: 90&80&180&. Si usa el índice de servo, tal vez desee verificarlo (convertir a inty luego haga coincidir el índice de bucle i) para asegurarse de que no haya ningún problema con su mensaje.

Tienes que comprobar que la devolución string desde readStringUntil no está vacío. Si la función se agota, no recibió suficientes datos y, por lo tanto, no ha intentado extraer su int los valores producirán resultados extraños.

void setup() 
    Serial.begin(9600);


void loop() 
    for(int i=1; i<=3; i++) 
        String servo = Serial.readStringUntil(':');
        if(servo != "")
            //here you could check the servo number
            String pos = Serial.readStringUntil('&');
            int int_pos=pos.toInt();
            Serial.println("Pos");
            Serial.println(int_pos);
        
    

valoraciones y comentarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *