2016-02-01 7 views
1

Débutant ici. J'essaie de concaténer les arguments d'un programme C++ dans un seul tableau char. Pour une raison quelconque, strcat ne tient pas compte de manière sélective argv[2] dans la boucle for:C++ strcat ignore un argument?

#include <cstring> 

int main(int argc, char *argv[]) { 

    char *argstr = argv[1]; 

    for(int i=2; i < argc; i++) { 
     argstr = std::strcat(argstr, " "); 
     argstr = std::strcat(argstr, argv[i]); 
    } 

    std::cout << argstr << std::endl; 

    return 0; 
} 

Le fichier est nommé qtimer. Ainsi, la sortie prévue de fonctionnement:

qtimer asdf 1 2 3

serait:

asdf 1 2 3

mais il est sortie:

asdf 2 3 (avec deux espaces après asdf)

Quelqu'un pourrait-il expliquer pourquoi c'est? Aussi, y a-t-il une meilleure façon de faire cela?

+1

'std :: strcat' semble juste faux! Vous ne devriez pas utiliser ces fonctions de la corbeille c, quand vous avez 'std :: string'. –

Répondre

10

Vous ajoutez à la chaîne stockée dans argv[1], mais vous ne savez pas qu'il y a de l'espace là. Vous écrasez la mémoire qui ne vous appartient pas.

Ce comportement n'est pas défini et tout peut arriver. Il est probable que la mémoire que vous écrasez est la mémoire où les autres arguments sont stockés, de sorte qu'au moment où vous y accédez, ils sont déjà endommagés.

Vous devez utiliser std::string pour les opérations de chaîne en C++, c'est beaucoup mieux et plus sûr.

+1

Pour être complet, j'ajouterais que pour fixer leur code, ils pourraient allouer un espace suffisamment grand (ou calculer exactement combien ils auraient besoin). Par exemple: 'char * argstr = malloc (1024); memset (argstr, 1024, 0); 'préparer un espace de 1k pour le résultat. – Sorin

+0

@Sorin Pourquoi l'allocation dynamique? Pour ce faire, vous pouvez, tout aussi facilement (encore plus facilement, puisque vous n'avez pas besoin de le libérer ensuite), créer un tableau sur la pile 'char buffer [1024] = {0}'. –

+0

1024 ne suffit pas. Vous devez boucler en calculant l'espace. –