paulo1205
(usa Ubuntu)
Enviado em 04/07/2019 - 01:46h
Ris1nG escreveu:
Agradeço pela resposta, entendi, no caso entao era so colocar o vetor para receber o valor da matriz dentro de um for por exemplo, pq ele ia armezanar nos 24 espaços do vetor tipo char * os 24 elementos da matriz bidimensional do tipo char?
O que vai estar contido nos ponteiros para
char : só sequências de caracteres (como
array de
bytes ) ou
strings (textos terminado com um
byte nulo)? Num caso ou noutro, terão cada um deles tamanhos idênticos, ou podem ter tamanhos muito discrepantes?
Suponha que você tenha o seguinte
array de ponteiros para
char que representam
strings .
// Uso ponteiros para caracteres contantes porque cada elemento é uma constante literal de string
// (C até aceitaria omitir o “const”, embora sejam efetivamente contantes; C++ dará erro se for omitido).
const char *coisas_boas_de_ouvir_ptr[5]={
"Eu te amo.",
"Obrigado!",
"Foi um prazer.",
"Volte sempre.",
"O SENHOR é meu pastor; nada me faltará.\n"
"Deitar-me faz em verdes pastos, guia-me mansamente às águas tranquilas.\n"
"Refrigera a minha alma; guia-me pelas veredas da justiça por amor do seu nome.\n"
"Ainda que eu andasse pelo vale da sombra do morte, não temeria mal algum, porque tu estás comigo; a tua vara e o teu cajado me consolam.\n"
"Preparas uma mesa perante mim na presença dos meus inimigos; unges a minha cabeça com óleo, e o meu cálice transborda.\n"
"Certamente que a bondade e a misericórdia me seguirão todos os dias da minha vida, e habitarei na Casa do SENHOR por longos dias."
};
Você tem aqui um primeiro elemento curto, que ocupa apenas 11 caracteres, um segundo ainda mais curto, com 10, o terceiro com 15, o quarto com 14, e quinto elemento bem mais longo, com 590 caracteres (usando codificação UTF-8 para o caracteres acentuados e c-cedilha). Se você fosse converter esse
array de ponteiros representando
strings para um
array de
arrays representando
strings , todos os
arrays representando
strings teriam de ter o mesmo comprimento, que teria de ser igual ao da maior
string .
char coisas_boas_de_ouvir_arr[5][590]={
"Eu te amo.",
"Obrigado!",
"Foi um prazer.",
"Volte sempre.",
"O SENHOR é meu pastor; nada me faltará.\n"
"Deitar-me faz em verdes pastos, guia-me mansamente às águas tranquilas.\n"
"Refrigera a minha alma; guia-me pelas veredas da justiça por amor do seu nome.\n"
"Ainda que eu andasse pelo vale da sombra do morte, não temeria mal algum, porque tu estás comigo; a tua vara e o teu cajado me consolam.\n"
"Preparas uma mesa perante mim na presença dos meus inimigos; unges a minha cabeça com óleo, e o meu cálice transborda.\n"
"Certamente que a bondade e a misericórdia me seguirão todos os dias da minha vida, e habitarei na Casa do SENHOR por longos dias."
};
// sizeof coisas_boas_de_ouvir_arr == 5*590 == 2950, embora apenas 640 (== 11+10+15+14+590) sejam úteis.
Como eu disse na mensagem anterior, para transformar (copiando) uma coisa na outra, você tem de ter tipos de dados que sejam compatíveis.
No sentido de
array de ponteiros para
array de
arrays , isso implicaria copiar caráter a caráter.
// Usa a declaração e definição de ‘coisas_boas_de_ouvir_ptr’ feita acima.
char destino[5][590]; // Sorte que eu sei o tamanho, mas note que mesmo assim eu vou me proteger contra sobretamanho, abaixo.
for(int n=0; n<5; n++){
if(coisas_boas_de_ouvir_ptr[n]!=NULL){
// Protejo contra a eventualidade de ponteiros nulos (possível num caso geral, embora não seja o nosso caso aqui).
strncpy(destino[n], coisas_boas_de_ouvir_ptr[n], (sizeof destino[n])-1); // Limito a quantidade de caracteres copiados, pois origem poderia ser maior que capacidade do destino, …
destino[n][(sizeof destino[n])-1]='\0'; // … e garanto que o terminador da strings estará presente o final.
}
else{
// Se o ponteiro for nulo, faço a string ficar vazia (uma alternativa seria gerar erro, mas preferi não usar isso aqui).
destino[n][0]='\0';
}
}
No sentido oposto, de
array de
arrays para
array de ponteiros, temos mais de uma opção: podemos duplicar as
strings , de modo análogo ao feito acima, ou podemos fazer com que os ponteiros apontem para exatamente as mesmas
strings que estão contidas no
array de
arrays .
// Alternativa 1: copiando strings.
// Usa a declaração e definição de ‘coisas_boas_de_ouvir_arr’ feita acima.
char *destino[5]; // Ou, se você preferir, “char **destino=malloc(5 * sizeof destino[0]); if(destino==NULL){ perror("malloc"); abort(); }”.
for(int n=0; n<5; n++){
size_t len=strlen(coisas_boas_de_ouvir_arr[n]);
destino[n]=malloc(len+1);
if(destino[n]==NULL){
perror("malloc");
abort();
}
do
destino[n][len]=coisas_boas_de_ouvir_arr[n][len]
while(len--);
}
/* Usa ‘destino’ até que ele não seja mais necessário, e seus ponteiros possam ser liberados. */
// Libera memória que foi dinamicamente alocada acima.
for(int n=0; n<5; n++)
free(destino[n]);
// Se você tiver alocado também ‘destino’ dinamicamente, não esqueça de “free(destino)”.
// Alternativa 2: apontando para os mesmo conteúdo das strings originais (tipos compatíveis).
char *destino[5]; // Ou, se você preferir, “char **destino=malloc(5 * sizeof destino[0]); if(destino==NULL){ perror("malloc"); abort(); }”.
for(int n=0; n<5; n++)
destino[n]=coisas_boas_de_ouvir_arr[n];
/*
A partir de agora, ‘destino[n]’ é praticamente um sinônimo de ‘coisas_boas_de_ouvir_arr[n]’, a não ser
que você faça com que ‘destino[n]’ passe a apontar para outro lugar.
Usa ‘destino’ até não ser mais necessário.
*/
// Se você tiver alocado ‘destino’ dinamicamente, não esqueça de “free(destino)”.
... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)