LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: joaopedrocmp em 21 de Abril de 2015, 10:30

Título: Dividir String em variaveis
Enviado por: joaopedrocmp em 21 de Abril de 2015, 10:30
Bom dia,

Damos o caso que tenho uma string :   

char str= "var1=01&var2=02&var3=03";

e quero dividir em:

int var1=01;
int var2=02;
int var3=03;

mas queria que a variavel fosse criada consoante o nome que viesse na string. Se por acaso viesse: variavel1=01 em vez de var1=01, criava a variavel variavel1 em vez de var1.

para ja tenho um exemplo que arrnajei na net. mas nao cria as variaveis a partir da string

Código: [Seleccione]
#include <string.h>

char sz[] = "Here; is some; sample;100;data;1.414;1020";
void setup()
{
 char *p = sz;
 char *str;
 Serial.begin(9600);
 while ((str = strtok_r(p, ";", &p)) != NULL) // delimiter is the semicolon
   Serial.println(str);
}

void loop(){}

generates this output:

Here
is some
sample
100
data
1.414
1020
Título: Re: Dividir String em variaveis
Enviado por: dropes em 21 de Abril de 2015, 10:49
Não podes ir criando variáveis ao longo do processo, elas são criadas no inicio, seja de um procedimento ou função.
Se queres retirar um valor de uma string para uma variável inteira, 1º tens de escolher a zona da string onde estão os valores, depois converter para numérico, só depois é que podes colocar na variável.
Título: Re: Dividir String em variaveis
Enviado por: jm_araujo em 21 de Abril de 2015, 10:57
Em C/C++ não podes criar variáveis dinamicamente (dessa maneira pelo menos). Uma solução seria criar um array ou lista de conjuntos nome/valor, ou algo pelo género.

Mas mais importante, porque é que quererias fazer algo assim? Explica para o que queres pode ser que te arranjem uma solução mais viável.
Título: Re: Dividir String em variaveis
Enviado por: senso em 21 de Abril de 2015, 12:42
O nome da variavel é psicológico, é simplesmente açucar sintático para uma posição(ou várias) de memória..
Título: Re: Dividir String em variaveis
Enviado por: dropes em 21 de Abril de 2015, 14:01
Nada impede que a saída da informação via série contenha o nome que consta na string, é uma questão de jogar com array de strings ter a mesma posição do array de variáveis inteiras, assim na string principal, retira-se o seu nome + o valor (em caracteres também), coloca-se o nome no str[0] (var. tipo string) e o valor no int[0] (var. tipo integer depois de convertido).

Isto foi só um exemplo para vários nomes e valores, que depende imenso do objectivo assim como o @jm_araujo referiu.
Título: Re: Dividir String em variaveis
Enviado por: Tiobel em 21 de Abril de 2015, 14:22
Podes utilizar este pseudo-código:

Código: [Seleccione]
char* string_var[5] = {
        "", "", "", "", "", ""  , ""
      };//cuts the received string into 6 pieces

      int i = 0;
      char * to_cut;

      to_cut = strtok (string_received, ",");
      while (to_cut != NULL)
      {
        string_var[i] = to_cut;
        i++;
        to_cut = strtok (NULL, " ,");
      }
     
      depois:
      int var_0 = atoi(string_var[0]);

Neste caso o separador da "string_received" é a virgula, mas podes utilizar outra coisa.
Depois convertes o valor do array num inteiro.
Título: Re: Dividir String em variaveis
Enviado por: joaopedrocmp em 21 de Abril de 2015, 15:17
Depois de ter pesado mehor, o que interessa nao é criar as variaveis consoante o nome que vem na string, mas sim a ordem delas.

Eu estou a ler uma string de um servidor Web com um conjunto de variaves para o arduino recolher os valores.

Não perco nada em talvez enviar as variaveis sempre pela mesma ordem na string, e apenas igualo uma variavel a cada numero dentro de "&"

em vez de enviar
char str= "var1=01&var2=02&var3=03";

vou enviar

char str= "01&02&03";

depois
faço qualquer coisa do genero:

int var1 = leitura do primeiro bloco
int var2 = leitura do 2º bloco
ect..

A vantagem é ter menos cadigo a escolher qual a variavel para onde vai.
e a desvantagem é que tem que seguir aquele protocolo e os dados terem que ser enviados pela mesma rdem


Título: Re: Dividir String em variaveis
Enviado por: jm_araujo em 21 de Abril de 2015, 16:14
Se é para um serviço Web, os "nomes" das variáveis não são arbitrários. Podes comparar o nome com o que queres e atribuir o valor associado à variável apropriada.
Título: Re: Dividir String em variaveis
Enviado por: joaopedrocmp em 21 de Abril de 2015, 16:24
O servidor vai actualizar os dados varias vezes, mas desde que no primeiro espaço (entre virgulas) seja a var1 e no segundo a var 2, nao precisa de ir la escrito que é a var1, porque naquea posição so pode ser aquela (segundo o protocolo).

basta entao igualar  arduinov1 ao primeiro valor e assi sucessivamente.

correto?

Fazer como disse o @tiobel em "x" no  string_var
Título: Re: Dividir String em variaveis
Enviado por: StarRider em 21 de Abril de 2015, 16:31
Podes utilizar este pseudo-código:

Código: [Seleccione]
char* string_var[5] = {
        "", "", "", "", "", ""  , ""
      };//cuts the received string into 6 pieces

      int i = 0;
      char * to_cut;

      to_cut = strtok (string_received, ",");
      while (to_cut != NULL)
      {
        string_var[i] = to_cut;
        i++;
        to_cut = strtok (NULL, " ,");
      }
     
      depois:
      int var_0 = atoi(string_var[0]);

Neste caso o separador da "string_received" é a virgula, mas podes utilizar outra coisa.
Depois convertes o valor do array num inteiro.

Boas,

Isso tem muito código desnecessário, se a ideia é fazer o parse de uma string para
converter os termos em numérico basta isto:

Código: [Seleccione]
      char * token;
      token = strtok (string_received, ",");
      while (token != NULL)
      {
        var_xpto_?? = atoi(token);
        token = strtok (NULL, " ,");
      }

Título: Re: Dividir String em variaveis
Enviado por: StarRider em 21 de Abril de 2015, 16:50
Depois de ter pesado mehor, o que interessa nao é criar as variaveis consoante o nome que vem na string, mas sim a ordem delas.

Eu estou a ler uma string de um servidor Web com um conjunto de variaves para o arduino recolher os valores.

Não perco nada em talvez enviar as variaveis sempre pela mesma ordem na string, e apenas igualo uma variavel a cada numero dentro de "&"

em vez de enviar
char str= "var1=01&var2=02&var3=03";

vou enviar

char str= "01&02&03";

depois
faço qualquer coisa do genero:

int var1 = leitura do primeiro bloco
int var2 = leitura do 2º bloco
ect..

A vantagem é ter menos cadigo a escolher qual a variavel para onde vai.
e a desvantagem é que tem que seguir aquele protocolo e os dados terem que ser enviados pela mesma rdem

Suponho que isso seja para fazer o parser de um GET HTTP ou coisa parecida, mas em
qualquer dos casos os "pares" devem ser respeitados por uma questão de manutenção
do código e evolução do mesmo. Usar pares na forma "field_x=value_y" garante que
se no futuro for necessário alterar/adicionar/remover/etc qualquer dos parâmetros isso
não vai requerer grande alteração no parser em si, alem de que deixa de existir o
constrangimento de ter que se respeitar a ordem com que os parâmetros são enviados.

Uma coisa bem implementada começa por separar os pares e à medida que estes vão
sendo lidos é tratar logo dos mesmos, ou seja,  algo no género:

Código: [Seleccione]
void processar_received(char *buf)
{
    char *token;
    token = strtok (buf, "&");
    while (token != NULL)   {
        processar_par(token);
        token = strtok (NULL, "&");
    }
}

void processar_par(char *par)
{
   char varname[20];
   int x=0;
 
   while (char[x] && (char[x]!='='))
       varname[x] = char[x++];
   varname[x] = 0;

  if (!strcmp(varname, "Xpto"))
     xpto = atoi(&par[x]);
  else if (!strcmp(varname, "Outra"))
     outra = atoi(&par[x]);
   ...
}

Abraços,
PA
Título: Re: Dividir String em variaveis
Enviado por: joaopedrocmp em 21 de Abril de 2015, 17:08
Obrigado,

quando chegar a casa ja vou passar isso para a pratica a ver o que sai ;)
Título: Re: Dividir String em variaveis
Enviado por: joaopedrocmp em 21 de Abril de 2015, 23:25
Boas starrider,
consegues ajudar mais com um exemplo? nao wstou a conseguir por em pratica.

obrigado
Título: Re: Dividir String em variaveis
Enviado por: Njay em 22 de Abril de 2015, 00:22
Qual é o problema? (Além do Star se ter enganado e ter metido "char" onde devias estar "par")
Título: Re: Dividir String em variaveis
Enviado por: StarRider em 22 de Abril de 2015, 19:00
Qual é o problema? (Além do Star se ter enganado e ter metido "char" onde devias estar "par")

Yap ... conta a intenção ;)

Título: Re: Dividir String em variaveis
Enviado por: StarRider em 22 de Abril de 2015, 19:24
Boas starrider,
consegues ajudar mais com um exemplo? nao wstou a conseguir por em pratica.

obrigado

Boas,

O meu exemplo era mais um pseudocódigo do que algo com um propósito funcional,
mas de qualquer forma vou alterar, mas tem em atenção que código genérico e que
não estou a testar.

Código: [Seleccione]
#include <string.h>

// Estou a assumir que vais passar parâmetros numéricos tal como
// no exemplo: "var1=01&var2=02&var3=03"
// Não estou a testar compilar isto, por isso se der erro posta as mensagens de erro

// PS: este código é para C99 ( ISO/IEC 9899:1999)

// comprimento máximo dos nomes das variáveis
#define VAR_NAME_LEN 20

// comprimento máximo dos parâmetros string
#define PAR_STR_LEN 20

// tens que definir as variáveis "var" antes, podes usar um valor por defeito
// para inicializar as mesmas
int var1=0;
int var2=0;
int var3=0;
int var4=0;
char varstr1[PAR_STR_LEN+1];
 /* etc */

void processar_par(char *par)
{
   char varname[VAR_NAME_LEN+1];
   int x=0;

   while (par[x] && (par[x]!='=') && (x<VAR_NAME_LEN))
       varname[x] = par[x++];
   if (par[x]!='=')
       return;
   varname[x++] = 0;

  if (!strcmp(varname, "var1"))
     var1 = atoi(&par[x]);
  else if (!strcmp(varname, "var2"))
     var2 = atoi(&par[x]);
  else if (!strcmp(varname, "var3"))
     var3 = atoi(&par[x]);
  // podes adicionar mais "vars" aqui
  // ...
  //  caso o parâmetro seja uma string podes usar isto:
  else if (!strcmp(varname, "str1")) {
     strncpy(varstr1, &par[x], 20);
     varstr1[PAR_STR_LEN] = 0;  // caso seja > 20 chars strncpy não faz o append do ZERO
  }
}

void processar_received(char *buf)
{
    char *token;
    token = strtok(buf, "&");
    while (token != NULL)   {
        processar_par(token);
        token = strtok (NULL, "&");
    }
}


char command[128] = "var1=1&var2=2&var3=3&str1=ola mundo";
int main(int argc, char *argv[])
{
    processar_received(command);
    printf("var1 = %d\n", var1);
    printf("var2 = %d\n", var2);
    printf("var3 = %d\n", var3);
    printf("str1 = %s\n", varstr1);
}

Abraços,
PA