Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Rorsch

Array de Strings dinâmico com Strings de tamanho fixo

Mensagens Recomendadas

Rorsch

Estou aqui às voltas com um código que preciso escrever em C. Tenho um ciclo que vai gerando strings de tamanho fixo (em char tagId[15]), e preciso ir adicionando-as a um Array de strings. Não sei à partida quantas strings vão ser geradas.

// Reads the Tag from the RFID Reader
if (nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti)) {

     // Converts the Tag ID from hex to String
     strcpy(tagId,"");

     for (uiPos=0; uiPos < ti.tia.uiUidLen; uiPos++) {
 sprintf(temp,"%02x",ti.tia.abtUid[uiPos]);
	 strcat(tagId,temp);
     }
(...)

Este bloco que código é executado inúmeras vezes (nunca sei quantas à partida), e após este for preciso ir adicionando o tagId a um Array de strings.


I would rather be a ghost drifting by your side as a condemned soul than enter heaven without you... Because of your love, I will never be a lonely spirit.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
falk0n

Tem mesmo de ser um array de strings ? ou poderias utilizar uma lista de strings ? Se utilizares uma lista de strings o problema fica facilitado. Se realmente necessitares de um array de strings (array de array de caracteres) penso que deverias criar um apontador de apontador de strings, em que depois poderias ir chamando o realloc (quando necessitasses) ou então criares uma estrutura de dados que te permita tirar partido de algumas propriedades do teu problema sem perderes assim tanto performance.

Boas programações,

Nuno Martins

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rorsch

Uma lista de Strings em C é implementada de que forma falk0n? Posso acede-la por indexação (i)?


I would rather be a ghost drifting by your side as a condemned soul than enter heaven without you... Because of your love, I will never be a lonely spirit.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
falk0n

Por podes, mas é caro, se quiseres aceder ao 10 elemento (e que não seja o ultimo) tens de atravessar a lista até ao 10 elemento (ou seja passar por todos os outros anteriores).

A lista é implementada utilizando uma estrutura com a cabeça da lista, e o numero de elementos que essa lista tem.

A cabeça da lista é um nó em que esse nó tem o elemento (neste caso uma string) e um apontador para o próximo elemento.

Mas uma vez que perguntaste se poderias aceder por indexação é porque provavelmente necessitas desse tipo de acesso, e neste tipo de estruturas esse acesso é caro, por isso o que talvez te sirva será mesmo fazer um criar um "char ** array_de_chars" , e possívelmente utilizares o realloc sempre que necessitares de aumentares o numero de elementos para que apontas.

Boas programações,

Nuno Martins

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rorsch

No caso de mais alguém precisar, fiz desta maneira:

int N;
typedef char Word[5+1];
Word *words = malloc(N * sizeof *words);
if (words != NULL) {
strcpy (words[0], "word1");
...
strcpy (words[5], "word6");
}


I would rather be a ghost drifting by your side as a condemned soul than enter heaven without you... Because of your love, I will never be a lonely spirit.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rorsch

Ao que parece este código não está a funcionar como deve ser (estou a usá-lo através do JNI, é um diabo para debug). O meu código é este:

int N = 0;
typedef char Tag[14];
Tag *tagsTmp = malloc(N * sizeof *tagsTmp);
(...)
strcpy(tagsTmp[tag_count], tagId); 
tag_count++;

A segunda parte do código está dentro de um ciclo que gera strings em tagId durante um período de tempo. O problema é que o array tagsTmp apresenta as strings erroneamente, e por vezes o código crasha simplesmente.

Correndo o mesmo código, mas definindo o tagsTmp como char *tagsTmp[2][14]; é o suficiente para evitar todos estes problemas, mas o ideal seria aceitar mais que duas tagId.


I would rather be a ghost drifting by your side as a condemned soul than enter heaven without you... Because of your love, I will never be a lonely spirit.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
TheDark

Estás a chamar o malloc com N=0? E a função sizeof está a ser chamada assim como mostras, sem parêntesis? Parece que funciona, mas não me parece uma sintaxe muito bonita...

Limitas muito o código que mostras. O que é que acontece ali no (...)? De onde vem o tagId? Como é que limitas o valor máximo de tag_count, de forma a não ultrapassar o tamanho actual do array?


Desaparecido.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rorsch

Estás a chamar o malloc com N=0? E a função sizeof está a ser chamada assim como mostras, sem parêntesis? Parece que funciona, mas não me parece uma sintaxe muito bonita...

Limitas muito o código que mostras. O que é que acontece ali no (...)? De onde vem o tagId? Como é que limitas o valor máximo de tag_count, de forma a não ultrapassar o tamanho actual do array?

A string tagId vem da conversão de um hexadecimal em string (como mostro no primeiro post). Basicamente tenho um código que guarda a identificação das tags RFID presentes no leitor. Enquanto houverem tags que ainda não foram identificadas vou gerando tagIds que guardo em tagsTmp.

Estou a chamar o malloc com N = 0, mas estou a ver que não é assim que se faz :D Também não limito o valor máximo de tag_count. Como posso declarar o tagsTmp correctamente?


I would rather be a ghost drifting by your side as a condemned soul than enter heaven without you... Because of your love, I will never be a lonely spirit.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
TheDark

O malloc recebe como parâmetro o número de bytes que queres alocar. Se o chamas com N * sizeof(Tag), sendo N = 0, estás a pedir para alocar 0 bytes. Não tenho a certeza, mas se estiver errado alguém me corrija: o comportamento da função malloc quando é chamada com 0 não está definido.

Tens que colocar em N o número de arrays que pretendes alocar inicialmente.


Desaparecido.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rorsch

E depois como vou alocando mais memória à medida que vou precisando?  :P


I would rather be a ghost drifting by your side as a condemned soul than enter heaven without you... Because of your love, I will never be a lonely spirit.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
TheDark

Depois, se chegares ao limite de strings que alocaste, tens que realocar o array, e copiar as strings existentes do antigo para o novo, libertando em seguida o antigo.

Essa seria a vantagem das listas sugeridas pelo falk0n: de cada vez que precisasses de adicionar uma string, só tinhas que alocar essa string e adicioná-la ao fim da lista. Com um array de strings, tens que alocar espaço para mais strings e copiar as antigas.

A melhor solução será baseada na tua utilização da colecção: será que vais fazer acessos sequenciais (aceder a várias strings seguidas) e adicionar strings muitas vezes (implicando realocação frequente do array de strings e subsequente cópia, no caso do array), favorecendo a lista? Ou será que até nem vais precisar de criar novas strings assim tantas vezes, e acedes às strings aleatoriamente, favorecendo o array?


Desaparecido.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rorsch

Pois, a ideia de listas parece ser o que mais se adequa à minha situação, vou gerar e aceder às strings sequencialmente. Sabem onde posso encontrar um exemplo para C? Tudo o que encontro é para C++ :/


I would rather be a ghost drifting by your side as a condemned soul than enter heaven without you... Because of your love, I will never be a lonely spirit.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.