collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Duvida Strings  (Lida 8918 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline Addax

  • Mini Robot
  • *
  • Mensagens: 68
Duvida Strings
« em: 16 de Junho de 2015, 15:45 »
Boa tarde,
Estou com um problema ao fazer um printf de um valor hexadecimal.
A minha duvida é a seguinte: se eu declarar uma variável, inicializa-la e fizer o printf funciona na perfeição. Abaixo está o código que estou a falar.
Código: [Seleccione]
int main()
{
char ch[33]={0x1D,0x56,0x01};
while(1)
{
printf("%s",ch);
}
}
Depois algures no código eu recebo por rs232 a seguinte string: "0x80,0x25,0x35", ou seja,
ch[0]=0
ch[1]=x
ch[2]=8
ch[3]=0
.....

Agora a minha duvida é a seguinte, como posso separar os diferentes hexadecimais de forma a ficar igual ao apresentado no printf acima?

(Não sei se estou a conseguir transmitir a minha duvida)

obrigado desde já
Cumprimentos

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Duvida Strings
« Responder #1 em: 16 de Junho de 2015, 15:55 »
Falta um \0 para terminar a string.
Porque é que não usas '0', 'a' para escrever um caracter em vez de andar com numeros, nem toda a gente decora a tabela ASCII.
Porque é que usas um array com 33 posições para usar 3?

Se queres imprimir um numero em formato hex usas %x
Avr fanboy

Offline Addax

  • Mini Robot
  • *
  • Mensagens: 68
Re: Duvida Strings
« Responder #2 em: 16 de Junho de 2015, 16:10 »
Eu depois de receber aquela string por rs232 volto a enviar para outro rs232.
No primeiro exemplo quem recebe a string interpreta e reage.
No segundo mesmo com o '\0' não reage. já tentei de várias formas e só no primeiro caso é que funciona

O 33 em vez do 3 foi um erro mas como isto é só um exemplo não faz diferença.

Offline KammutierSpule

  • Mini Robot
  • *
  • Mensagens: 1.481
Re: Duvida Strings
« Responder #3 em: 16 de Junho de 2015, 16:11 »
Desculpa nao entendi as duvidas (tambem so li uma vez) mas reparo que ha uma mistura de problemas ai, vou tentar fazer um pequeno sumario talvez possa ajudar.

Código: [Seleccione]
printf("%s", "imprime uma string de caracteres que termina com o caracter zero" ); // Nota: "" termina automaticamente a string com um \0. Este zero final nao é impresso (mas ocupa memoria), apenas significa que deve terminar o envio da string.
printf("%c", 0x20); // Imprime o caracter com o valor hexadecimal 0x20 , que corresponde na tabela ascii ao caracter espaço.
printf("%c", '!'); // Mesma coisa mas imprime o caracter ! que corresponde ao valor hexadecimal 0x21
printf("%d", '!'); // Imprime o valor do caracter !, que é 33, ou seja, os caracteres 3 duas vezes "33"
printf("%X, '!'); // Imprime o valor hexadecimal do caracter !, ou seja, 21, imprime o caracter '2' e o caracter '1' == "21"
printf("%X, 0x21); // Mesma coisa, imprime "21"
printf("%c", 0x21); // Imprime o caracter com o valor hexadecimal 0x21 que corresponde ao ! na tabel ascii.

Edit: mais exemplos:
Código: [Seleccione]
char c_array[4] = { 0x30, 0x31, 0x32, 0x33 };

printf("%s",  c_array); // Crash! Isto nao é correcto, nao existe uma terminacao no array conhecida com zero, logo nao sabe quando vai parar de escrever caracteres.

for( int i=0; i<4; i++) printf("%c", c_array[i] ); // Imprime "0123"
for( int i=0; i<4; i++) printf("%x", c_array[i] ); // Imprime "30313233"
for( int i=0; i<4; i++) printf("%d", c_array[i] ); // Imprime "48495051"
« Última modificação: 16 de Junho de 2015, 16:22 por KammutierSpule »

Offline Addax

  • Mini Robot
  • *
  • Mensagens: 68
Re: Duvida Strings
« Responder #4 em: 17 de Junho de 2015, 12:58 »
Obrigado KammutierSpule e senso pela ajuda.
Problema e duvida resolvidos.

Isto é um exemplo.
Recebo por rs232 a seguinte string: "0x80,0x25,0x35", nas diferentes posições do vetor ch[]
ch[0]=0
ch[1]=x
ch[2]=8
ch[3]=0
ch[4]=,
ch[5]=0
.....

O que resolvi fazer foi:
Código: [Seleccione]
char recebe[100]=0;
char recebe_mod[100]=0;
char envia[3]=0;
int dec=0;
int k=0,j=0,q=0;

for(k=0;k<=strlen(recebe);k++)
{
   if(recebe[k]==0x30 && recebe[k+1]==0x78)
   {
     recebe_mod[q]=recebe[k+2];
     recebe_mod[q+1]=recebe[k+3];
     q=q+2;
   }
}

for(k=0;k<=strlen(recebe_mod);k++)
{
  switch(recebe_mod[k])
  {
    case '0':
      envia[j]=0;
      j++;
      break;
    case '1':
      envia[j]=1;
      j++;
      break;
    case '2':
      envia[j]=2;
      j++;
      break;
    ...
    default:
      j=0;
  }
  if(j==2)
  {
    dec=(int)envia[0]*16+(int)envia[1];
    printf("%c",(char)dec);
    j=0;
  }
}

Partilho aqui o que fiz porque pode dar jeito a alguém

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Duvida Strings
« Responder #5 em: 17 de Junho de 2015, 13:19 »
Ahh, tu queres é parsar uma string que tem números num formato hexadecimal.
É melhor escrever assim, é mais correcto porque o 0 não fica ambiguo:

ch[0]='0'
ch[1]='x'
ch[2]='8'
ch[3]='0'
ch[4]=','
ch[5]='0'

Eu em 1º lugar tentaria mudar o formato de envio para eliminar o "0x", que só dificulta, passando a receber "80,25,35".

Depois tens 2 funções que te ajudam nesse parsing: strtok (parte uma string por um separador) e strtol (converte uma string num número, no último argumento indicas a base numérica, que no teu caso seria 16 (hexadecimal)). Dá uma olhada nestas funções porque mesmo que não precises delas agora, quem sabe no futuro (e é um bom exercício re-escreveres o código usando-as).

Offline Addax

  • Mini Robot
  • *
  • Mensagens: 68
Re: Duvida Strings
« Responder #6 em: 17 de Junho de 2015, 14:33 »
Njay, obrigado pela dica.
Eu só não optei por alterar a mensagem recebida porque isto é para integrar num projeto e assim não tenho que estar a alterar o que já está feito.
quanto às duas funções de parsing, vou ver e se não forem utilizadas agora, fico com o conhecimento para uma próxima

StarRider

  • Visitante
Re: Duvida Strings
« Responder #7 em: 17 de Junho de 2015, 15:11 »
Boas,

Grande complicação para algo tão simples:

Código: [Seleccione]
char recebe[100] = "0x80,0x25,0x35";
uchar envia[3];
char *token;
int idx=0;

token = strtok(recebe, ",");
while (token != NULL)   {
    envia[idx++]=strtol(token, NULL, 16);
    token = strtok (NULL, ",");
}


PS: não te esqueças dos includes:
#include <string.h>
#include <stdlib.h>

Abraços,
PA
« Última modificação: 17 de Junho de 2015, 15:14 por StarRider »

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Duvida Strings
« Responder #8 em: 17 de Junho de 2015, 15:26 »
Olha, boa, não tinha reparado que o strtol também aceitava hexs começados com o 0x :D

Então já agora e só para tornar isso mais à prova de crashes misteriosos:

const int cMaxEnvia = 3;
char recebe[100] = "0x80,0x25,0x35";
uchar envia[cMaxEnvia];
char *token;
int idx=0;

token = strtok(recebe, ",");
while ( (idx < cMaxEnvia) && (token != NULL) )   {
    envia[idx++]=strtol(token, NULL, 16);
    token = strtok (NULL, ",");
}


StarRider

  • Visitante
Re: Duvida Strings
« Responder #9 em: 17 de Junho de 2015, 15:42 »
Olha, boa, não tinha reparado que o strtol também aceitava hexs começados com o 0x :D

Então já agora e só para tornar isso mais à prova de crashes misteriosos:

const int cMaxEnvia = 3;
char recebe[100] = "0x80,0x25,0x35";
uchar envia[cMaxEnvia];
char *token;
int idx=0;

token = strtok(recebe, ",");
while ( (idx < cMaxEnvia) && (token != NULL) )   {
    envia[idx++]=strtol(token, NULL, 16);
    token = strtok (NULL, ",");
}


Yap, mas a prova do "crash" era para ser ele a descobrir ;)

Abraços,
PA

Offline Addax

  • Mini Robot
  • *
  • Mensagens: 68
Re: Duvida Strings
« Responder #10 em: 17 de Junho de 2015, 16:46 »
Obrigado StarRider e Njay.
O código que apresentaste é muito mais simples.
o único problema para este caso especifico é que no recebe pode estar algures 0x00. ao fazer o printf do envia ele faz como se fosse '\0', ou seja, é como se fosse o fim da string

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Duvida Strings
« Responder #11 em: 17 de Junho de 2015, 17:03 »
Qual é o problema? Agora já sabes quantos bytes são (idx), portanto...

Código: [Seleccione]
for (int i = 0; i < idx; i++)
{
    printf("%c", envia[i]);
}

Offline Addax

  • Mini Robot
  • *
  • Mensagens: 68
Re: Duvida Strings
« Responder #12 em: 17 de Junho de 2015, 17:40 »
tens toda a razão. pensei mal
problema resolvido. com um código bem mais simples e reduzido que inicialmente o meu

obrigado a todos que participaram no tópico

StarRider

  • Visitante
Re: Duvida Strings
« Responder #13 em: 17 de Junho de 2015, 18:01 »
Qual é o problema? Agora já sabes quantos bytes são (idx), portanto...

Código: [Seleccione]
for (int i = 0; i < idx; i++)
{
    printf("%c", envia[i]);
}

Ou ainda mais "compacto"  ;)

Código: [Seleccione]
while(idx--)
    printf("%c", envia[idx]);

Abraços,
PA

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Duvida Strings
« Responder #14 em: 17 de Junho de 2015, 18:02 »
É mais compacto mas o resultado não é o mesmo, ficas com os bytes impressos pela ordem inversa ;)