Pages: [1]   Go Down
Author Topic: Partir cadena (char)  (Read 1515 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A ver si me podéis guiar con esto, hago una petición y me devuelve un char a = "uno;dos;tres;" y quería poder partirlo y formar un String o cadena con cada elemento ( uno dos tres ) y poder acceder a él, algo como:

char[0]= uno
char[1]= dos
char[2]= tres

¿Puedo hacerlo según esta o tengo que pasar de char a char*?
Estoy mirando por internet y foros y no doy con la solución. smiley-confuse

Un saludo  smiley-wink
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 133
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

debes buscar una funcion slip o parecido, lo que hace es buscar un delimitadorr , en tu caso es el  ' ;'  y te se lo separa
para este caso encontre pero para string, deberias convertir el cgar a string.

Code:
void setup() {
  // put your setup code here, to run once:

}


void loop() {
  // put your main code here, to run repeatedly:
 
 
String split = "hi this is a split test";


String word3 = getValue(split, ' ', 2);
Serial.println(word3);

}

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 || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mirare lo que me comentas a ver que hacemos...  smiley
He conseguido partir el propio char pero me falta guardar cada valor independiente o dentro de un String para poder acceder a cada uno.

Code:
#include <String.h>

char *strtok( char *str1, const char *str2 );

void setup()
{

Serial.begin(9600);
char str[] = "uno;dos;tres;cuatro;";
char delimitadores[] = ";";
char *resultado = NULL;
resultado = strtok( str, delimitadores );

while( resultado != NULL )
    {
    Serial.println(resultado);
    resultado = strtok( NULL, delimitadores );
    }

}

void loop () {

}

El resultado me da:

uno
dos
tres
cuatro


Un saludo  smiley-wink
Logged

Palencia, Spain
Offline Offline
Sr. Member
****
Karma: 25
Posts: 478
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si no vas a necesitar la cadena "original" más tarde, podrías sustituir el caracter separador por \0 y asignar directamente las direcciones de donde empieza cada tramo. Entiendo que lo que quieres dividir es una cadena recibida de algún sitio, no declarada en el propio código, ¿no? porque en ese caso lo lógico sería declarar directamente el array entre llaves.
Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si no vas a necesitar la cadena "original" más tarde, podrías sustituir el caracter separador por \0 y asignar directamente las direcciones de donde empieza cada tramo. Entiendo que lo que quieres dividir es una cadena recibida de algún sitio, no declarada en el propio código, ¿no? porque en ese caso lo lógico sería declarar directamente el array entre llaves.

La cadena original no la voy a necesitar, lo que me interesa seria poder guardar cada dato (tramo) en una variable y tener acceso (almacenar) esas variables. La cadena se recibe como respuesta a una petición si, no la declaro en el código, y su longitud puede variar, por eso tengo que partirla y guardar cada tramo en algún sitio.
También pensé en guardarlo en una tarjeta SD y con arduino leer ese .txt ya que me guardaría cada tramo en una linea (leo la linea y al llegar al salto de linea se que ya es un tramo), e igual es mas sencillo así y guardarlo en una variable cada tramo que hacerlo directamente.

Un saludo  smiley-wink
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 133
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#include <String.h>


void setup()
{

 
Serial.begin(9600);
char str[] = "uno;dos;tres;cuatro;";
char *pch;
int i=0;
 pch = strtok (str,";");
String buff[sizeof(str)];
  while (pch != NULL)
  {
   buff[i]=(pch);
    pch = strtok (NULL, ";");i++;
  }
 
 
  for(int x=0;x<i;x++){
 Serial.println( buff[x]);
 
  }
  i=0;

}

void loop () {

 
 
 
}


By  Omni
Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tengo un problema y es que lo que recibo es:

char a = "uno;dos;tres;cuatro;";

que es distinto a:

char a[]= "uno;dos;tres;cuatro;";

Ya que el char a que leo es que proveniente de client.read();
Lo que hago es una petición por GET y leo el resultado, ese resultado quiero "dividirlo" y almacenarlo para luego poder acceder a ello cuando necesite.
La verdad que me estoy enterando de muchas cosas nuevas, gracias.  smiley-wink
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 133
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

que tenes conEctado ?? ETHERNET ??

ALGO ASI ESTAS LEYENDO ??

if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

NO SE POQUE PUBLICAS UN ARRAY CUANDDO NO LO TENIAS
Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pido disculpas por ese fallo mio ya que de primeras lo explique bien pero buscando ejemplos por un lado y otro no me di cuenta de que postee un array, lo siento ya que la gente se molesta en ayudar como para encima "engañar" respecto a lo que se quiere conseguir, no estamos para perder el tiempo si no para ayudarnos un@s a otr@s.
Justamente tengo lo que tu comentas del char c es lo que yo llamo char a, estoy conectado a ethernet si, leo la respuesta de esa manera.

Un saludo y pido disculpas de nuevo.  smiley-confuse
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vamos una subidita, porque yo iba a abrir un tema igual pero ya que esta este, y con permiso de Arduastur, me voy a kedar por aqui a ver como va la cosa, que llevo dos dias con las cadenas, arrays, arrays de cadenas, punteros de cadenas y la madre que las.... a todas y no consigo guardar caracteres sueltos en una variable para que me formen una cadena.

Espero que no te moleste la intrusion tio.
Saludos.
Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vamos una subidita, porque yo iba a abrir un tema igual pero ya que esta este, y con permiso de Arduastur, me voy a kedar por aqui a ver como va la cosa, que llevo dos dias con las cadenas, arrays, arrays de cadenas, punteros de cadenas y la madre que las.... a todas y no consigo guardar caracteres sueltos en una variable para que me formen una cadena.

Espero que no te moleste la intrusion tio.
Saludos.

Pilla sitio donde quieras  smiley-wink
Logged

Palencia, Spain
Offline Offline
Sr. Member
****
Karma: 25
Posts: 478
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Suponiendo que sepas el tamaño máximo que va a tener la cadena entera, y el número máximo de partes en que la vas a dividir, yo tal vez haría algo así (no está probado, pero para que te hagas una idea de por dónde quiero ir):

Code:
#define maxsize 1000
#define maxparts 100
void setup() {
    Serial.begin(9600);
}

void loop() {
    char buffer[maxsize]; // buffer para recibir la cadena
    char *parte[maxparts]; // array de punteros a cada subcadena
    char caracterRecibido; // caracter que llega por Serial
    int indicebuffer=0, // posición del buffer donde se escribirá el caracter que llegue
        comienzo=0,    // posición del buffer donde comienza la subcadena que se está recibiendo
        indiceparte=0; // índice de subcadena recibiéndose
    if (Serial.available()){
        do{
            delay(5);
            caracterRecibido=Serial.read(); // almacenamos temporalmente el caracter recibido
            if(caracterRecibido==';'|| caracterRecibido=='\0'){ // Si se recibe ; o fin de cadena
                buffer[indicebuffer]='\0';    // se escribirá fin de cadena de todos modos. Hemos terminado de recibir una parte.
                parte[indiceparte]=buffer+comienzo; // asignamos al puntero de parte actual la dirección del buffer + índice caracter donde comenzaba la subcadena
                indicebuffer++;    // avanzamos el índice donde recibir el siguiente caracter
                indiceparte++;    // Lo que venga corresponderá a la siguiente parte
                comienzo=indicebuffer; //la siguiente parte comenzará después del ; recibido
            } else {
                buffer[indicebuffer]=caracterRecibido; //recibimos un caracter normal dentro de la subcadena que se está procesando
                indicebuffer++;    // avanzamos el índice donde recibir el siguiente caracter
            }
        } while(caracterRecibido!='\0' && indicebuffer<maxsize && indiceparte<maxparts); // salimos si recibimos final de cadena, se sobrepasa el tamaño de buffer o el número de subcadenas
    }
}
Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Suponiendo que sepas el tamaño máximo que va a tener la cadena entera, y el número máximo de partes en que la vas a dividir, yo tal vez haría algo así (no está probado, pero para que te hagas una idea de por dónde quiero ir):

Code:
#define maxsize 1000
#define maxparts 100
void setup() {
    Serial.begin(9600);
}

void loop() {
    char buffer[maxsize]; // buffer para recibir la cadena
    char *parte[maxparts]; // array de punteros a cada subcadena
    char caracterRecibido; // caracter que llega por Serial
    int indicebuffer=0, // posición del buffer donde se escribirá el caracter que llegue
        comienzo=0,    // posición del buffer donde comienza la subcadena que se está recibiendo
        indiceparte=0; // índice de subcadena recibiéndose
    if (Serial.available()){
        do{
            delay(5);
            caracterRecibido=Serial.read(); // almacenamos temporalmente el caracter recibido
            if(caracterRecibido==';'|| caracterRecibido=='\0'){ // Si se recibe ; o fin de cadena
                buffer[indicebuffer]='\0';    // se escribirá fin de cadena de todos modos. Hemos terminado de recibir una parte.
                parte[indiceparte]=buffer+comienzo; // asignamos al puntero de parte actual la dirección del buffer + índice caracter donde comenzaba la subcadena
                indicebuffer++;    // avanzamos el índice donde recibir el siguiente caracter
                indiceparte++;    // Lo que venga corresponderá a la siguiente parte
                comienzo=indicebuffer; //la siguiente parte comenzará después del ; recibido
            } else {
                buffer[indicebuffer]=caracterRecibido; //recibimos un caracter normal dentro de la subcadena que se está procesando
                indicebuffer++;    // avanzamos el índice donde recibir el siguiente caracter
            }
        } while(caracterRecibido!='\0' && indicebuffer<maxsize && indiceparte<maxparts); // salimos si recibimos final de cadena, se sobrepasa el tamaño de buffer o el número de subcadenas
    }
}

El problema es que no se en cuantas partes dividirlo porque puede variar la cantidad de bytes recibidos, pero no es problema porque contando el numero de delimitadores (en mi caso tengo ';') ya se cuantas partes voy a tener y por el tamaño le daré un valor que vea que no va a ser superado y si lo supera lo varío y pongo mayor a mano y listo.
Voy a probar "la idea" que me has puesto a ver que tal, lo que busco es saber por donde van los tiros no quiero ni vengo a pedir que me hagan el codigo, me gustan los retos y poder superarme a mi mismo pero para eso hay que saber por donde ir y ahora mismo no se por donde atacar.  smiley-mr-green

Un saludo y Gracias  smiley-wink
Logged

Palencia, Spain
Offline Offline
Sr. Member
****
Karma: 25
Posts: 478
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Esa era mi intención. Darte una "idea" a partir de la que desarrollar tu código y que a partir de ahí desarrolles el tuyo propio. Después de todo, creo que estamos aquí para aprender, no para que nos hagan las cosas. Para eso hay empresas que por un módico precio... smiley-wink
Si finalmente el tamaño de buffer y/o el número de subcadenas va a ser muy imprevisible y la gestión de memoria crítica como para no poder reservar un espacio sobrado y ya está, todavía te queda la posibilidad de asignar memoria dinámicamente, pero eso conlleva otras complejidades.
Espero haberte ayudado, y si finalmente te funciona la idea, exponlo aquí.
Saludos.
Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 46
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lo que estoy probando estos dias es guardar toda la lectura del buffer en un .txt dentro de una tarjeta SD, para luego abrir ese .txt y leerlo, mejor que directamente leerlo según me llega, así de paso tengo un lugar físico donde tener la información recibida guardada y para consultarla cuando quiera y también para en un futuro añadirle un reloj y así poder tener fecha y hora de cada vez que se accede a ello, pero eso para mas adelante, por ahora ya tengo entretenimiento con esto.  smiley-mr-green

Un saludo y gracias por la ayuda  smiley-wink
Logged

Pages: [1]   Go Up
Jump to: