2011-11-08 9 views
5

dichiaro il seguente matrice:Come trovo la lunghezza della matrice "char *" in C?

char* array [2] = { "One", "Two"}; 

passo questa matrice a una funzione. Come posso trovare la lunghezza di questo array nella funzione?

+1

char stelle == puntatore a carattere –

+2

Per inciso, usando 'I' invece di 'i' probabilmente contribuirà ad evitare l'euristica" è una domanda ragionevole "(oltre a rendere la domanda più facile da leggere per i madrelingua inglesi). – sarnold

risposta

17

Non è possibile trovare la lunghezza di un array dopo averlo passato a una funzione senza ulteriore sforzo. Avrete bisogno di:

  1. utilizzare un contenitore che memorizza le dimensioni, come ad esempio vector (raccomandato).
  2. Passa la dimensione insieme. Questo probabilmente richiederà la minima modifica al codice esistente e sarà la soluzione più rapida.
  3. Utilizzare un valore sentinella, come le stringhe C . Ciò rende la ricerca della lunghezza dell'array un'operazione lineare e se dimentichi il valore sentinella il tuo programma si bloccherà probabilmente. Questo è il modo peggiore per farlo nella maggior parte delle situazioni.
  4. Utilizzare i modelli per detrarre la dimensione dell'array mentre lo si passa. Si può leggere su qui: How does this Array Size Template Work?

Nel caso ve lo stiate chiedendo, la maggior parte delle persone rammarico il fatto che le stringhe C funzionano in questo modo.

+0

Così hanno inventato le stringhe B. –

+0

@MooingDuck collegamento per favore :) Google è mamma sull'oggetto –

+0

In modo appropriato il nome corretto è [BSTR] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms221069 (v = vs.85) .aspx) (Le persone odiano questi più di archi C) –

6

Quando si passa un array, c'è NON un modo semplice per determinare le dimensioni all'interno della funzione.

È possibile sia passare la dimensione della matrice come parametro o uso std :: vector < std :: string>

Se vi sentite particolarmente avventurosi è possibile utilizzare some advanced template techniques

In poche parole somiglia a

template <typename T, size_t N> 
void YourFunction(T (&array)[N]) 
{ 
    size_t myarraysize = N; 
} 
+0

sì è quello che sto facendo attualmente, ma volevo rimuovere quel parametro in più. vabbè – bubbles

+0

Esiste anche una classe std :: array . –

+3

@bubbles 'int main (argc, char ** argv)'. Se fosse semplice main sarebbe fatto in modo diverso. –

0

Se intendi per quanto tempo sono state aggiunte tutte le stringhe insieme.

int n=2; 
int size=0; 
char* array [n] = { "One", "Two"}; 

for (int i=0;i<n;++i) 
    size += strlen(array[i]; 

Aggiunto:

sì questo è quello che al momento sto facendo, ma ho voluto rimuovere quella più paramater. vabbè -

destinata probabilmente ad avere una cattiva risposta per questo, ma si può sempre utilizzare il primo puntatore per memorizzare le dimensioni, fino a quando non si deferenza o scambiate per essere effettivamente un puntatore.

char* array [] = { (char*)2,"One", "Two"}; 

long size=(long)array[0]; 
for(int i=1; i<= size;++i) 
    printf("%s",array[i]); 

Oppure si potrebbe NULL interrompere l'allineamento

char * array [] = { "One", "Due", (char *) 0};

for(int i=0;array[i]!=0;++i) 
{ 
    printf("%s",array[i]); 
} 
0

Non è possibile ottenere la dimensione della matrice dal puntatore. Si potrebbe semplicemente terminare l'array con un puntatore NULL. In questo modo la tua funzione può cercare il puntatore NULL per conoscere la dimensione, o semplicemente interrompere l'elaborazione dell'input una volta che ha colpito il NULL ...

2

C sta facendo un po 'di inganno alle tue spalle.

void foo(int array[]) { 
    /* ... */ 
} 

void bar(int *array) { 
    /* ... */ 
} 

Entrambi sono identici:

6.3.2.1.3: Tranne quando è l'operando dell'operatore sizeof o unario & operatore, o è una stringa letterale utilizzato per inizializzare una matrice, un'espressione che ha tipo 'array di tipo' '' viene convertita in un'espressione con tipo '' puntatore per digitare '' che punta all'elemento iniziale dell'oggetto array e non è un lvalue. Se l'oggetto array ha una classe di archiviazione di registro, il comportamento non è definito.

Di conseguenza, non si sa, all'interno foo() o bar(), se si dovesse chiamato con una matrice, una porzione di un array o un puntatore a una singola intero:

int a[10]; 
int b[10]; 
int c; 

foo(a); 
foo(&b[1]); 
foo(&c); 

alcune persone piace scrivere le loro funzioni come: void foo(int *array) solo per ricordare a se stessi che non erano realmente superato un serie, ma piuttosto un puntatore a un numero intero e potrebbero non esserci più numeri interi altrove nelle vicinanze. Ad alcune persone piace scrivere le loro funzioni come: , per ricordarsi meglio di ciò che la funzione si aspetta venga passata ad esso.

Indipendentemente dal modo in cui ti piace fare, se volete sapere quanto tempo l'array è, hai un paio di opzioni:

  1. Passo lungo un paramenter lunghezza di troppo. (Pensa a int main(int argc, char *argv)).
  2. Progettare l'array in modo che ogni elemento non sia NULL, eccetto l'ultimo elemento . (Pensa a char *s="almost a string"; o execve(2).)
  3. Progetta la tua funzione in modo che ci voglia qualche altro descrittore degli argomenti . (Pensate al printf("%s%i", "hello", 10); - la stringa descrive gli argomenti . printf(3) utilizza la gestione dell'argomento stdarg(3), ma potrebbe facilmente essere un array.)
+1

curiosità: 'argv' fa entrambi i punti 1 e 2. – u0b34a0f6ae

Problemi correlati