Eu estou tentando criar uma matriz de seqüências de caracteres em C. Se eu usar este código:
char (*a[2])[14];
a[0]="blah";
a[1]="hmm";
O gcc me dá "aviso: atribuição do tipo de ponteiro incompatível". Qual é a maneira correta de fazer isso?
edit: Estou curioso para saber por que isso deve dar um aviso ao compilador, pois, se o fizer printf(a[1]);
, ele imprime corretamente "hmm".
char (*a[2])[14]
é uma matriz de dois ponteiros para uma matriz de 14 caracteres.char (*a[2])[14]
- comece pora
, mova para a direita: "matriz de dois", mova para a esquerda: "ponteiro para", suporte completo para ler direito: "array de forteen", lidos da esquerda: "char" ... Coloque-o em conjunto e temos "um é matriz de dois ponteiros para matrizes de forteen caracteres"char *str
vez dechar* str
. Vindo de uma experiência em Delphi / Pascal, eu estava muito acostumado com essa última maneira, até encontrar tipos mais complexos. A primeira maneira ainda me parece feia, mas torna a notação de tipo mais consistente (IMO).Respostas:
Se você não quiser alterar as cordas, você pode simplesmente fazer
Ao fazer assim, você alocará uma matriz de dois ponteiros para
const char
. Esses ponteiros serão configurados para os endereços das seqüências estáticas"blah"
e"hmm"
.Se você deseja alterar o conteúdo real da string, é necessário fazer algo como
Isso alocará duas matrizes consecutivas de 14
char
s cada, após as quais o conteúdo das seqüências estáticas será copiado para elas.fonte
Existem várias maneiras de criar uma matriz de cadeias em C. Se todas as cadeias tiverem o mesmo comprimento (ou pelo menos o mesmo comprimento máximo), você simplesmente declara uma matriz 2-d de caractere e atribui conforme necessário:
Você também pode adicionar uma lista de inicializadores:
Isso pressupõe que o tamanho e o número de strings no inicializador correspondam às dimensões da matriz. Nesse caso, o conteúdo de cada literal de cadeia de caracteres (que é uma matriz de caracteres com terminação zero) é copiado para a memória alocada para strs. O problema com essa abordagem é a possibilidade de fragmentação interna; se você tiver 99 cadeias de caracteres com 5 caracteres ou menos, mas uma cadeia com 20 caracteres, 99 terão no mínimo 15 caracteres não utilizados; isso é um desperdício de espaço.
Em vez de usar uma matriz 2-d de char, você pode armazenar uma matriz 1-d de ponteiros em char:
Observe que, nesse caso, você alocou apenas memória para reter os ponteiros nas seqüências de caracteres; a memória para as próprias seqüências de caracteres deve ser alocada em outro lugar (como matrizes estáticas ou usando
malloc()
oucalloc()
). Você pode usar a lista de inicializadores como no exemplo anterior:Em vez de copiar o conteúdo das constantes de seqüência de caracteres, você está simplesmente armazenando os ponteiros para elas. Observe que as constantes de string podem não ser graváveis; você pode reatribuir o ponteiro, assim:
Mas você pode não conseguir alterar o conteúdo da string; ou seja,
pode não ser permitido.
Você pode usar
malloc()
para alocar dinamicamente o buffer para cada sequência e copiar para esse buffer:BTW,
Declara a como uma matriz de 2 elementos de ponteiros para matrizes de 14 elementos de caracteres.
fonte
malloc
chamada.T [N]
é convertida em uma expressão do tipoT *
e o valor da expressão é o endereço do primeiro elemento. Portanto, se você escreveustr = "foo"
, tentaria atribuir o endereço do primeiro caractere de"foo"
à matrizstr
, o que não funciona. Veja esta resposta para mais detalhes.char *strs[NUMBER_OF_STRINGS] = {0};
Isso ajuda a evitar problemas futuros ao inicializarstrs
paraNULL
. Um monte de gente ler este post quando o fazem buscas do Google em matriz de strings em C.Ack! Cordas constantes:
Se eu me lembro bem.
Ah, e você deseja usar strcpy para atribuição, não o operador =. strcpy_s é mais seguro, mas não está nos padrões C89 nem C99.
Atualização: Thomas diz que
strlcpy
é o caminho a percorrer.fonte
Aqui estão algumas de suas opções:
A vantagem
a2
é que você pode fazer o seguinte com literais de stringE para
a3
você, faça o seguinte:Pois
a1
você terá que usarstrcpy()
(melhor aindastrncpy()
) mesmo ao atribuir literais de string. O motivo é quea2
, ea3
são matrizes de ponteiros e você pode fazer com que seus elementos (ou seja, ponteiros) apontem para qualquer armazenamento, enquantoa1
é uma matriz de 'matriz de caracteres' e, portanto, cada elemento é uma matriz que "possui" seu próprio armazenamento ( o que significa que ele é destruído quando sai do escopo) - você só pode copiar itens para o armazenamento.Isso também nos leva à desvantagem de usar
a2
ea3
- já que eles apontam para armazenamento estático (onde literais de cadeia de caracteres são armazenados) cujo conteúdo não pode ser alterado com segurança (ou seja, comportamento indefinido), se você deseja atribuir literais não de cadeia de caracteres ao elementos dea2
oua3
- você primeiro terá que alocar dinamicamente memória suficiente e, em seguida, seus elementos apontarão para essa memória e, em seguida, copiarão os caracteres para ela - e, em seguida, será necessário desalocar a memória quando terminar.Bah - já sinto falta do C ++;)
ps Deixe-me saber se você precisar de exemplos.
fonte
Ou você pode declarar um tipo de estrutura, que contém um caractere arry (1 string), eles criam uma matriz das estruturas e, portanto, uma matriz com vários elementos
Uma das vantagens disso em relação a qualquer outro método é que isso permite que você escaneie diretamente a string sem precisar usar
strcpy
;fonte
No ANSI C:
fonte
char* foo, bar;
qual é o tipo debar
?Se as strings são estáticas, é melhor você:
Embora não faça parte do ANSI C básico, é provável que seu ambiente suporte a sintaxe. Essas cadeias são imutáveis (somente leitura) e, portanto, em muitos ambientes, usam menos sobrecarga do que a construção dinâmica de uma matriz de cadeias.
Por exemplo, em pequenos projetos de microcontroladores, essa sintaxe usa memória de programa em vez de (geralmente) memória ram mais preciosa. O AVR-C é um exemplo de ambiente que suporta essa sintaxe, mas o mesmo ocorre com a maioria dos outros.
fonte
Se você não deseja acompanhar o número de strings na matriz e deseja iterá-las, basta adicionar uma string NULL no final:
fonte
Os literais de string são
const char *
s.E seu uso de parênteses é estranho. Você provavelmente quer dizer
que declara uma matriz de dois ponteiros para caracteres constantes e os inicializa para apontar para duas constantes de string codificadas.
fonte
Seu código está criando uma matriz de ponteiros de função. Experimentar
ou
em vez de.
Veja wikibooks para matrizes e ponteiros
fonte
Olá, você pode tentar o seguinte:
um bom exemplo de uso, matriz de strings em c, se você quiser
fonte
Aqui tente isso !!!
fonte
Estava faltando uma matriz mais dinâmica de strings, em que a quantidade de strings poderia variar dependendo da seleção em tempo de execução, mas, caso contrário, as strings deveriam ser corrigidas.
Acabei por codificar o snippet de código assim:
char** ev
seleciona o ponteiro para as seqüências de caracteres da matriz e count seleciona a quantidade de seqüências de caracteres usando a_countof
função (Semelhante asizeof(arr) / sizeof(arr[0])
).E há conversão extra de Ansi para unicode usando
A2T
macro, mas isso pode ser opcional para o seu caso.fonte
Uma boa maneira é definir uma string para você.
É realmente assim tão simples.
fonte
;
, e como isso cria uma matriz de seqüências de caracteres ?