2012-01-28 14 views
5

Czy musisz ręcznie przechodzić przez tablicę jeden raz i uzyskać liczbę strlen każdej tablicy znaków, zsumować ją, przydzielić miejsce docelowe z wartością zsumowaną, a następnie ponownie wykonać pętlę w tablicy?Jak iterować po tablicy tablic znaków wc?

Jak znaleźć rozmiar tablicy zawierającej tablice znaków, aby można było nad nią powtarzać?

+1

Kod pomoże nam zrozumieć, o co pytasz. – user7116

+0

Wygląda na to, że chcesz skopiować tablicę ciągów C. Czy to prawda? – vitaut

+0

Chcę w końcu połączyć ciągi w tablicy w jeden ciąg znaków. Należy wiedzieć, ile miejsca pamięci należy przeznaczyć na docelowy ciąg znaków. Nie wiem, w jaki sposób wiesz, co umieścić jako warunek kończący w pętli for, tj. Jaka jest długość tablicy. –

Odpowiedz

7

Jak znaleźć rozmiar tablicy, która zawiera tablice znaków, dzięki czemu można iteracyjne nad nimi?

Istnieją dwa sposoby:

  1. zapisywanie liczby ciągów w tablicy, gdy przeznaczy ją w zmiennej.
  2. Przydziel dodatkową liczbę char* na końcu tablicy i umieść w niej wskaźnik zerowy jako wskaźnik, podobny do tego, w jaki sposób znak NUL jest używany do zakończenia ciągu znaków.

Innymi słowy, przy przydzielaniu tablicy trzeba wykonać własną księgę, ponieważ C nie da pożądanych informacji. Jeśli zastosujemy się do drugiego sugestię, można uzyskać całkowitą liczbę znaków w tablicy ciągów z

size_t sum_of_lengths(char const **a) 
{ 
    size_t i, total; 
    for (i = total = 0; a[i] != NULL; i++) 
     total += strlen(a[i]); 
    return total; 
} 

Nie zapomnij zarezerwować miejsca dla '\0' gdy robi rzeczywistego konkatenacji.

+0

Idziemy. Dzięki, że wszystko odpowiada. –

+1

Potrzebuje również zwrócić + 1, ponieważ ma zero, prawda? –

+0

... lub po prostu użyj sizeof (array)/sizeof (entry), aby uzyskać długość, jeśli naprawdę masz tablicę (nie wskaźnik - NIE są one takie same). Wiele osób (ja także przez ostatnie 10 lat) uważa, że ​​tablice i wskaźniki są takie same, ale nie są - tablice automatycznie zwyrodniają się do wskaźnika, jeśli zajdzie taka potrzeba. na przykład int a [10] = {0}; sizeof (a)/sizeof (int) da u 10; int * a = malloc (10 * sizeof (int)); sizeof (a) == sizeof (int *) w tym przypadku – griffin

0

Zgaduję, że chcesz połączyć ciągi. Jeśli tak, tak. Musisz wiedzieć, ile miejsca chcesz, zanim go przydzielisz.

W rzeczywistości można użyć realloc, ale tak naprawdę wystarczy skopiować poprzedni ciąg za każdym razem i znacznie mniej skutecznie.

Niektóre kod: (zakładając char *s[] i int n)

int i,l=1; 
for (i=0;i<n;i++) l+=strlen(s[i]); 
char *r=malloc(l); 
r[0]=0; 
for (i=0;i<n;i++) strcat(r,s[i]); 

Edycja: W niektórych komentarzach, strcat jest nieskuteczna, gdy znasz długość. (. I nadal wolą ponieważ przydzielić pamięci w jednym czasie) Niektóre bardziej efektywny kod jest:

int i,l=1; 
for (i=0;i<n;i++) l+=strlen(s[i]); 
char *r=malloc(l); 
char *d=r; 
for (i=0;i<n;i++) { 
srtcpy(d,s[i]); 
d+=strlen(s[i]); 
} 
+0

To użycie 'strcat' jest niezwykle kosztowne: powoduje, że algorytm działa w czasie O (n²), podczas gdy może być liniowy. –

+0

W jaki sposób można osiągnąć liniowość? Częścią mojego pytania jest ustalenie, co n ma w tym przypadku. –

1

Zakładam, że staramy się ciąg znaków, który jest połączeniem wszystkich ciągów w tablicy.

Istnieją 2 sposoby osiągnięcia tego celu:

  1. zrobić 2 karnety, jak sugerują, zsumowanie długości w pierwszym przejeździe, przeznaczając ciąg docelowy, a następnie dołączenie sznurki w drugim przejściu

  2. Wykonaj 1 podanie. Zacznij od przydzielenia bufora do pewnego rozmiaru. Dołącz ciągi, śledząc całkowity rozmiar. Jeśli nie masz wystarczającej ilości miejsca na ciąg znaków, prześlij ponownie bufor za pomocą realloc(). Najbardziej efektywną metodą realokacji będzie dwukrotne zwiększenie wielkości bufora.

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

char *nstrdup(char **args); 
int main (int argc, char **argv) 
{ 
char * this; 

this = nstrdup(argv+1); 
printf("[%s]\n", this); 

return 0; 
} 

char *nstrdup(char **args) 
{ 
size_t len, pos; 
char **pp, *result; 

len = 0; 
for (pp = args; *pp; pp++) { 
     len += strlen (*pp); 
     } 
result = malloc (1+len); 

pos = 0; 
for (pp = args; *pp; pp++) { 
     len = strlen (*pp); 
     memcpy(result+pos, *pp, len); 
     pos += len; 
     } 
result[pos] = 0; 
return result; 
} 
+0

Nie podoba mi się meta. (Nie rozumiem interfejsu). Sądzę, że ludzie, którzy edytują białe znaki (w jakiejś korporacyjnej formie kanonicznej), są niższymi formami życia. Proszę odejdź. ** PO PROSTU NIE DOTKNIJ MOJE ŹRÓDŁO ** redaktorzy whitespae. Wróć do java, jeśli nie możesz odczytać źródła. – wildplasser

+0

[meta] proszę dodać opcję akceptacji/ODRZUCENIA tych fałszywych zmian w nazewnictwie. – wildplasser

Powiązane problemy