2016-02-19 2 views
-1

J'essaie de copier les éléments individuels de argv dans un deuxième tableau. J'utilise strncpy pour le faire.strncpy de ** char à * char [] ne copiant pas le dernier élément

Voici une version dépouillée qui réplique le problème.

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

int main(int argc, char *argv[]) 
{ 
    printf("%d\n", argc); 
    char *argvarray[argc]; 
    int arrlen; 

    //int j; 
    for(int j=0; j< argc; j++){ 
     arrlen = arrlen + strlen(argv[j]); 
    } 

    printf("size of argv: %d\n", arrlen); //see if size is right 
    strncpy(*argvarray, *argv, arrlen); 

    for(int j=0; j< argc; j++){ 
     printf("value of j: %d\n", j); //to see what's going on 
     printf("%s\n", argv[j]); 
     printf("%s\n", argvarray[j]); //gets 1st element no problem 
    } 

    return 0; 
} 

Si je passe 1 arg aux principaux copies il le premier élément de argv-argvarray mais le second n'est pas copié. Si je passe plus de 1 argument, il se sépare sur strncpy().

Pourquoi cela se produit-il? Quelle est la meilleure façon de copier tous les éléments d'un tableau char (en particulier les tableaux de char déclarés dans les définitions de fonctions) vers d'autres tableaux de char sans connaître la taille avant, comme dans le cas de argv?

+2

suivant Vous n'allouer de la mémoire à laquelle les éléments de 'argvarray' pourraient pointer. –

+1

'arrlen' n'est pas initialisé. –

+0

Merci les gars, j'apprécie l'aide, et votre patience pendant que j'apprends. –

Répondre

3
arrlen = arrlen + strlen(argv[j]); 

arrlen est utilisé non initialisé (comportement indéfini).

Et comme l'a souligné @ PeterA.Schneider, vous avez besoin de place pour chaque élément de argvarray, utilisez malloc avant strncpy ou strdup

+0

Merci j'apprécie tous les commentaires constructifs. –

1

Vous êtes confus au sujet de tableaux vs pointeurs.

Si vous déclarez un tableau char tab[2][3], il sera stocké en mémoire jointive:

[h][e][y][y][o][u] (a simple example). 

Mais ici, vous avez des pointeurs, donc char (*tab)[2] est un tableau de deux pointeurs:

tab = [0x1234][0x5678] 
0x1234 = "hey" 
0x5678 = "you" 

strncpy copie des parties contiguës de la mémoire. Pour copier argv, copiez chaque pointeur au lieu (appel malloc + strcpy un pour chaque char* est l'option la plus facile)

(voir aussi @ réponse de AlterMann, ce qui est correct aussi bien)

+0

OUI! Les tableaux donnent des coups de pied à mes fesses. Les pointeurs ne sont pas beaucoup mieux. Si je n'avais pas besoin d'une meilleure compréhension de C, je préférerais probablement passer du temps à jongler avec des couteaux. Je vais y arriver finalement si (j'espère) –

+0

@JackGalt bonne chance :) – Ven

1
  1. arrlen n'est pas initialisées . Vous augmentez sa valeur, puis essayez de l'utiliser en tant que paramètre pour strncpy. Le comportement du programme sera indéfini. Écrivez plutôt int arrlen = 0;.

  2. argvarray est un tableau de pointeurs vers char. Vous n'allouez aucune mémoire pour chaque élément. *argvarray est équivalent à argvarray[0] qui est un char* qui ne pointe à rien. Ainsi, le comportement de strncpy sera indéfini.

0

En dehors de cela arrlen variable n'a pas été initialisées

int arrlen; 

et comme résultat la valeur de la variable après l'exécution de la boucle

for(int j=0; j< argc; j++){ 
    arrlen = arrlen + strlen(argv[j]); 
} 

sera indéterminée cet appel

strncpy(*argvarray, *argv, arrlen); 

n'a pas de sens et a un comportement indéfini.

Je pense que ce que vous entendez est le

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

int main(int argc, char *argv[]) 
{ 
    printf("%d\n", argc); 
    char *argvarray[argc]; 

    for (int i = 0; i < argc; i++) 
    { 
     argvarray[i] = malloc(strlen(argv[i]) + 1); 
     strcpy(argvarray[i], argv[i]); 
    } 

    for (int i = 0; i < argc; i++) 
    { 
     printf("value of i: %d\n", i); //to see what's going on 
     printf("%s\n", argv[i]); 
     printf("%s\n", argvarray[i]); //gets 1st element no problem 
    } 

    for (int i = 0; i < argc; i++) free(argvarray[i]); 

    return 0; 
} 
+0

Merci un million. Je vois comment les autres réponses étaient fondamentalement les mêmes que les vôtres, mais votre exemple d'utilisation a vraiment aidé à le clarifier. Réponse de qualité !! –

+0

@JackGalt Pas du tout. Nous les débutants devraient s'entraider. –