2012-01-11 14 views
8

Jugar con punteros en C es divertido (en realidad no).Puntero al conjunto de cadenas en C

Tengo varias matrices de cadenas quiero manifestar de una manera fácil, preferentemente algo como:

arrayOfStrings1 = {"word1", "word2", etc. }; 
arrayOfStrings2 = {"anotherword1", "anotherword2", etc. }; 
arrayOfStrings3 = etc. 
etc. 

Algo parecido a una matriz de traducción (pero no del todo), por lo que quiero ser capaz de cambiar entre estos durante el tiempo de ejecución. Para que quiero un puntero pointerToArrayOfStrings que puedo cambiar como:

pointerToArrayOfStrings = arrayOfStrings1; 
doStuff(); 
pointerToArrayOfStrings = arrayOfStrings2; 
doSomeOtherStuff(); 

En mi ingenua comprensión de matrices de cadenas y punteros a ellos, esto es lo que he intentado:

// Danish transforms 
const unsigned char* da_DK[] = {"b","bb","c","c","cc","d","dd","e","f","ff","g","gg","h","hh","j","j","jj","k","k","kk","l","l","l","l","ll","m","mm","n","n","nn","p","pp","r","r","r","rr","s","s","s","ss","t","t","tt","v","v","vv","æ"}; 

// British english transforms 
const unsigned char* en_GB[] = {"a","a","a","a","a","a","a","a","a","a","a","a","a","age","ai","aj","ay","b","cial","cian","cian","dj","dsj","ea","ee","ege","ei","ei","eigh","eigh","f","f","f","g","g","gs","i","i","i","j","j","k","ks","kw","l","m","n","n","o","r","s","s","sd","sdr","sion","sion","sj","sj","tial","tion","tion","tj","u","u","u","u","w","ye","ye","z"}; 

    // More languages.... 

const unsigned char** laguageStrings; 

// Assign language 
if (streq(language, "da-DK")){ 
    laguageStrings= da_DK; 
} 
else if (streq(language, "en-GB")){ 
    laguageStrings= en_GB; 
} 
else 
     return 0; 
} 

El lenguaje es un char * que contiene el idioma "en-GB", "da-DK", etc., streq() es solo una función de comparación de cadenas casera (algo más rápido que strcmp()).

Para abreviar, dependiendo del compilador, este enfoque puede funcionar, informar las advertencias del compilador o compilar, pero dar resultados inesperados.

¿Cuál sería la forma correcta de resolver este problema?

+0

¿Cuál es el problema? –

+2

Debe finalizar sus matrices de cadenas con un puntero NULL para poder recorrerlas con sensatez: 'const char * strs [] = {" aa "," bb ", NULL};' –

+0

Dependiendo del compilador, no funciona.Al compilador GNU de Linux le gusta y funciona, XCODE no lo hace y produce algunos errores extraños. – Woodgnome

Respuesta

19

Hay dos formas de trabajar con una matriz de caracteres (cadenas) en C. Son los siguientes:

char a[ROW][COL]; 
char *b[ROW]; 

La representación pictórica está disponible como comentario en línea en el código.

Sobre la base de la forma en que desea representar el conjunto de caracteres (cadenas), se puede definir el puntero a la de la siguiente manera

char (*ptr1)[COL] = a; 
    char **ptr2 = b; 

Ellos son fundamentalmente diferentes tipos (de una manera sutil) y así los punteros a ellos también son ligeramente diferentes.

El siguiente ejemplo muestra las diferentes formas de trabajar con cadenas en C y espero que lo ayude a comprender mejor la matriz de caracteres (cadenas) en C.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

#define ROW 5 
#define COL 10 

int main(void) 
{ 
    int i, j; 
    char a[ROW][COL] = {"string1", "string2", "string3", "string4", "string5"}; 
    char *b[ROW]; 

    /* 

    a[][] 

     0 1 2 3 4 5 6  7 8 9 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 1 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 2 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 3 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 4 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 5 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 

    */ 

    /* Now, lets work on b */  
    for (i=0 ; i<5; i++) { 
     if ((b[i] = malloc(sizeof(char) * COL)) == NULL) { 
      printf("unable to allocate memory \n"); 
      return -1; 
     } 
    } 

    strcpy(b[0], "string1"); 
    strcpy(b[1], "string2"); 
    strcpy(b[2], "string3"); 
    strcpy(b[3], "string4"); 
    strcpy(b[4], "string5"); 

    /* 

     b[]    0 1 2 3 4 5 6 7  8 9 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 1 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 2 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 3 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 4 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 5 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 

    */ 

    char (*ptr1)[COL] = a; 
    printf("Contents of first array \n"); 
    for (i=0; i<ROW; i++) 
     printf("%s \n", *ptr1++); 


    char **ptr2 = b; 
    printf("Contents of second array \n"); 
    for (i=0; i<ROW; i++) 
     printf("%s \n", ptr2[i]); 

    /* b should be free'd */ 
    for (i=0 ; i<5; i++) 
     free(b[i]); 

    return 0; 
} 
+0

Entonces, si quisiera definir mi matriz de cadenas como 'char * [COLS]', me veo forzado a 'malloc()' y luego 'strcpy()'? No hay forma de que pueda inicializarlo con una lista de cadenas como '{" string1 "," string2 ", ...}'? – Woodgnome

+0

Lo sentimos, se suponía que era 'char * [ROWS]' – Woodgnome

+2

@Woodgnome Sí, no se puede asignar una cadena a 'char []' o 'char *' como asignar un valor entero a una variable entera. Para la cadena necesitas usar funciones de biblioteca de cadenas como 'strcpy()' –

1

¿Cuál sería la forma correcta de resolver este problema?

Bueno, la forma correcta sería utilizar una biblioteca específicamente diseñada para tratar con interfaces multilenguaje, por ejemplo gettext.

Otra forma, aunque más irregular, sería utilizar un hash table (también conocido como "diccionario" o "mapa hash" o "mapa asociativo" en otros idiomas/tecnologías): Looking for a good hash table implementation in C

Probablemente no es la respuesta que estabas buscando, pero has hecho la pregunta incorrecta al problema correcto.