2010-03-02 31 views
11

Ho una matrice di stringhe che quando eseguo l'iterazione e stampo i suoi elementi mi dà risultati inaspettati.Array di stringhe in C

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

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

quando chiamo show_currencies() ottengo questo in uscita.

EURGBPUSDJPYCNY - GBPUSDJPYCNY - USDJPYCNY - JPYCNY - CNY - 

Qualcuno può spiegare questo comportamento.

Grazie

+0

qualsiasi compilatore decente dovrebbe dare un errore o almeno un avvertimento per questo – chappar

+1

@chapper, @martani: non ho una copia dello standard c vicino, ma penso che in questo caso il byte NUL rimanga in silenzio esplicitamente consentito dallo standard. Almeno una volta, ci sarebbe stata una ragionevole quantità di codice che usava questa tecnica per inizializzare i char array di dimensioni fisse, perché è molto più conciso che elencare semplicemente i valori char uno per uno. –

risposta

14

Ti manca le terminazioni nul le stringhe sono in realtà 4 caratteri. Ogni stringa ha poi terminato di scrivere il terminatore nullo * della stringa precedente *. Prova invece:

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

* Come sottolineato da CAF non è "over scrivendo terminatore null della stringa precedente", come il terminatore null non viene mai copiato nella matrice. È un colpo di fortuna che la stringa non ha output confuso dopo l'ultimo '-'.

+0

Sì, sarà così ... Devi lasciare spazio nell'array per il terminatore null e il contenuto effettivo ... –

+0

dannazione, mi ci è voluto così tanto tempo per trovare come dichiarare gli array di stringhe, quindi Ho perso la lunghezza di ogni stringa: D grazie per l'aiuto effeminato – 0xFF

+0

, che non funziona (è un errore in fase di compilazione). È necessario dichiarare la dimensione di tutti tranne la dimensione più a sinistra (il compilatore deve sapere per quanto tempo una riga deve gestire l'indicizzazione). –

2

Change

char currencies[][3] 

a

char currencies[][4] 

stringhe in C sono NULL terminati, per rendere la loro gestione (in stampa, la copia, ecc) più facile. esempio: char str[] = "ABC"; dichiarerà una stringa di 4 caratteri con \0 come ultimo carattere (indice 3).

Come suggerimento ogni volta che si stampa un array di caratteri si ottengono risultati imprevisti che si potrebbe voler verificare se l'array di caratteri è terminato NULL o meno.

8

Stai dichiarando che è sbagliato. Questo funzionerà. E 'solo consente al compilatore di istituire un array di puntatori-a-const-chars:

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

EDIT: il che rende un array a due dimensioni, come la risposta di Charles Beattie, lavori troppo, a condizione di allocare lo spazio per il nulla . Inoltre, specifica che i caratteri sono const, per Christoph.

+0

in realtà entrambi funzionano (se si lascia spazio per lo zero finale nel codice originale), ma la versione potrebbe essere migliore in quanto i compilatori avranno un tempo più semplice per ottimizzarlo; in entrambi i casi, dovresti aggiungere qualificatori 'const', anche se – Christoph

+0

entrambe le dichiarazioni sono diverse. Nel caso dell'OP, sta dichiarando un doppio array di caratteri, dove la dichiarazione è una matrice di puntatori const-char. Quindi, nel tuo caso, non può modificare il contenuto dell'array, cioè non può fare cose come le valute [0] [1] = 'x'; – chappar

+0

Esatto, Chappar. Non sembra che abbia intenzione di modificarlo. –

0

Sicuro. "EUR" ha una lunghezza di quattro caratteri: tre per le lettere, una per il carattere null che termina. Dato che stai specificando esplicitamente array di tre caratteri, il compilatore sta troncando, e così i tuoi dati sono legati insieme. Sei fortunato che apparentemente ci sia un carattere zero alla fine dell'array, oppure potresti avere tutti i tipi di spazzatura. Cambia la tua dichiarazione in char currencies[][4].

0

mio C è piuttosto arrugginito, ma provate:

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

Sono solo curioso di sapere cosa succede

+1

Il compilatore dovrebbe emettere un avviso. – ezpz

+2

Lo stesso avrà le stringhe lunghe 5 caratteri. '" EUR \ 0 "è equiv {'E', 'U', 'R', '\ 0', '\ 0'}' –

2

Non è un array di stringhe, ma una serie di array-di- char. È possibile utilizzare:

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

per consentire stringhe di diverse lunghezze.

+0

+1 da parte mia per un modo di evitare il conteggio .. –