2010-03-02 11 views
11

Tengo una matriz de cadenas que cuando repito e imprimo sus elementos me da resultados inesperados.Conjuntos de cadenas en C

char currencies[][3] = {"EUR", "GBP", "USD", "JPY", "CNY"}; 

void show_currencies() 
{ 
    int i; 
    for(i=0; i<5; i++) 
    { 
     printf("%s - ", currencies[i]); 
    } 
} 

cuando llamo a show_currencies() Lo consigo en la salida.

EURGBPUSDJPYCNY - GBPUSDJPYCNY - USDJPYCNY - JPYCNY - CNY - 

¿Alguien puede explicar este comportamiento?

Gracias

+0

cualquier compilador decente debería dar error o al menos advertencia para este – chappar

+1

@chapper, @martani: No tengo una copia del estándar c a mano, pero creo que dejar caer silenciosamente el byte NUL en este caso es explícitamente permitido por el estándar. Al menos al mismo tiempo, habría habido una cantidad razonable de código que utilizó esta técnica para inicializar matrices de caracteres fijos, porque es mucho más conciso que simplemente enumerar los valores de caracteres uno a uno. –

Respuesta

14

Te estas perdiendo los terminadores nul las cuerdas son en realidad 4 caracteres. Cada cadena termina escribiendo el terminador nulo * de la cadena anterior. Pruebe su lugar:

char currencies[][4] = {"EUR", "GBP", "USD", "JPY", "CNY"}; 

* Como se ha señalado por la CAF no está "escribiendo sobre terminador nulo de la cadena anterior" como el terminador nulo no se copia en la matriz. Es un golpe de suerte que la cuerda no tenga una salida distorsionada después del '-' final.

+0

Sí, eso será ... Tiene que dejar espacio en su matriz para el terminador nulo, así como el contenido real ... –

+0

maldita sea, me tomó tanto tiempo encontrar cómo declarar matrices de cadenas, luego Me perdí la longitud de cada cadena: D gracias por la ayuda – 0xFF

+0

ephemient, eso no funciona (es un error en tiempo de compilación). Debe declarar el tamaño de todas las dimensiones, excepto la que está más a la izquierda (el compilador debe saber cuánto tiempo una fila manejará la indexación). –

2

Cambio

char currencies[][3] 

a

char currencies[][4] 

cadenas en C están terminada en nulo, para que su manipulación (en la impresión, copia, etc.) más fácil. ejemplo: char str[] = "ABC"; declarará una cadena de 4 caracteres con \0 como último carácter (índice 3).

Como consejo cada vez que imprime una matriz de caracteres obtiene resultados inesperados, es posible que desee comprobar si la matriz de caracteres tiene terminación NULL o no.

8

Lo está declarando incorrecto. Esto funcionará Simplemente deja que el compilador de configurar una matriz de punteros-a-const-chars:

const char *currencies[] = {"EUR", "GBP", "USD", "JPY", "CNY"}; 

EDIT: Por lo que es una matriz de dos dimensiones, como la respuesta de Charles Beattie, también funciona, siempre se puede asignar espacio para la hipótesis nula . Además, especifique que los caracteres son const, según Christoph.

+0

en realidad, ambos funcionan (si deja espacio para el cero de terminación en el código original), pero su versión podría ser mejor ya que los compiladores tendrán un tiempo más fácil para optimizar esto; en ambos casos, debe agregar calificadores 'const', aunque – Christoph

+0

ambas declaraciones son diferentes. En el caso de OP, él está declarando una matriz de caracteres doble, mientras que su declaración es una matriz de punteros const char. Entonces, en su caso él no puede modificar el contenido de la matriz, quiero decir que no puede hacer cosas como monedas [0] [1] = 'x'; – chappar

+0

Correcto, chappar. No parece que tenga la intención de modificarlo. –

0

Sure. "EUR" tiene cuatro caracteres de longitud, tres para las letras, una para el carácter nulo de terminación. Dado que especifica explícitamente matrices de tres caracteres, el compilador está truncando, por lo que los datos se unen. Tienes suerte de que al parecer hay un cero carácter al final de la matriz, o puedes obtener todo tipo de basura. Cambie su declaración al char currencies[][4].

0

Mi C es bastante oxidado, pero trate:

char currencies[][3] = {"EUR\0", "GBP\0", "USD\0", "JPY\0", "CNY\0"}; 

Tengo curiosidad de saber lo que ocurre

+1

El compilador debería emitir una advertencia. – ezpz

+2

Lo mismo sucederá ya que sus cadenas tienen 5 caracteres de longitud. '" EUR \ 0 "es equiv {'E', 'U', 'R', '\ 0', '\ 0'}' –

2

Usted no tiene una matriz de cadenas, sino un conjunto de matriz-de- carbonizarse. Puede usar:

char* currencies[] = {"EUR", "GBP", "USD", "JPY", "CNY"}; // untested 

para permitir cadenas de diferentes longitudes.

+0

+1 de mí por una forma de evitar contar ... –