2012-01-28 30 views
5

¿Tiene que recorrer manualmente la matriz una vez y obtener un recuento de los valores de cada matriz de caracteres, sumarlo, asignar destino con el valor sumado y luego recorrer nuevamente la matriz?¿Cómo se itera sobre una matriz de matrices de caracteres en c?

¿Cómo se encuentra el tamaño de la matriz que contiene las matrices de caracteres para que pueda iterar sobre ellas?

+1

Algún código nos ayudaría a entender qué es lo que estás preguntando. – user7116

+0

Parece que desea copiar la matriz de cadenas C. ¿Está bien? – vitaut

+0

Quiero finalmente concatenar las cadenas de la matriz en una sola cadena. Necesita saber cuánto espacio de memoria asignar para la cadena de destino. No entiendo cómo sabes qué poner como la condición de terminación en el ciclo for, es decir, cuál es la longitud de la matriz. –

Respuesta

7

¿Cómo se encuentra el tamaño de la matriz que contiene los conjuntos de caracteres para que pueda iterar sobre ellos?

Hay dos maneras:

  1. registrar el número de cadenas en la matriz cuando le sitúa en una variable.
  2. Asigne un char* adicional al final de la matriz y almacene un puntero nulo en ella como un centinela, similar a la forma en que se utiliza un carácter NUL para terminar una cadena.

En otras palabras, tiene que hacer su propia contabilidad al asignar la matriz porque C no le dará la información deseada. Si sigue la segunda sugerencia, se puede obtener el número total de caracteres en el array de cadenas con

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; 
} 

No se olvide de reservar espacio para una '\0' cuando se hace la concatenación real.

+0

Ahí vamos. Gracias que responde todo. –

+1

También necesita devolver +1 ya que está basado en cero, ¿verdad? –

+0

... o simplemente use sizeof (array)/sizeof (entrada) para obtener la longitud si realmente tiene una matriz (no un puntero, NO son lo mismo). Muchas personas (yo también durante los últimos 10 años) piensan que las matrices y punteros son iguales, pero no lo son: las matrices se degenerarán automáticamente en punteros si es necesario. p.ej. int a [10] = {0}; sizeof (a)/sizeof (int) te dará 10; int * a = malloc (10 * sizeof (int)); sizeof (a) == sizeof (int *) en este caso – griffin

0

Supongo que quiere concatenar las cadenas. Si es así, sí. Debe saber cuánto espacio desea antes de asignarlo.

De hecho, puede usar realloc, pero en realidad es solo copiar la cadena anterior cada vez, y mucho menos efectiva.

Algunos código: (suponiendo char *s[] y 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]); 

Edit: Como algunos comentarios, strcat es ineficaz cuando se conoce la longitud. (. Yo prefiero que ya que asignar la memoria de una sola vez) algo más de código efectiva es:

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

Este uso de 'strcat' es increíblemente caro: hace que el algoritmo se ejecute en tiempo O (n²) mientras que podría ser lineal. –

+0

¿Cómo se puede lograr lineal? @asaelr parte de mi pregunta es cómo averiguar qué es n en este caso. –

1

Asumo que está tratando de hacer una cadena que es la concatenación de todas las cadenas de la matriz.

Hay 2 maneras de hacer esto:

  1. hacer 2 pases como usted sugiere, sumando las longitudes en la primera pasada, la asignación de la cadena de destino, y luego cambiarle las cuerdas en la segunda pasada

  2. Hacer 1 pase. Comience por asignar el búfer a algún tamaño. Agregue las cuerdas, controlando el tamaño total. Si no tiene espacio suficiente para una cadena, reasigne el almacenamiento intermedio con realloc(). El método más eficiente de reasignación será duplicar el tamaño del búfer cada vez.

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

No me gusta el meta. (No entiendo la interfaz). Creo que las personas que editan el espacio en blanco (en algún tipo de forma canónica corporativa) son formas de vida inferiores. Por favor vete. ** SIMPLEMENTE NO TOCAR MI FUENTE ** usted editores de whitespae. Vuelve a Java si no puedes leer la fuente. – wildplasser

+0

[meta] agregue una opción para aceptar/RECHAZAR estas ediciones falsas de espacio en blanco nazi. – wildplasser

Cuestiones relacionadas