2015-07-19 2 views
-1

J'essaie de passer des arguments de ligne de commande que je concatène ensuite correctement pour générer des commandes shell afin que je puisse les exécuter en utilisant system() (je sais que ce n'est pas conseillé et il y a de meilleurs moyens pour le faire de cette façon seulement). Mais il y a un problème dans la concaténation des chaînes que je passe Voici le code (j'ai tout imprimé à chaque étape pour avoir une compréhension claire et non je n'ai pas encore écrit les appels system(), d'abord j'ai besoin de trier concaténation dehors):strcat fonctionnant paranormalement

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
int main(int argc, char *argv[]) { 
    char* path=argv[1]; 
    char* oldName=argv[2]; 
    char* newName=argv[3]; 
    char* command1="cd "; 
    char* command2="ren "; 
     printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 
    strcat(command1,path); 
    printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 
    strcat(oldName," "); 
    strcat(oldname,newName); 
    printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 
    strcat(command2,oldName); 
    printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 

    return 0; 
} 

Cependant, après la concaténation de la commande 1 au chemin, tout est corrompu.

http://i.stack.imgur.com/vPxxD.png

+0

voir [modifier chaîne littérale] (http://stackoverflow.com/questions/ 5464183/modifying-string-literal) – amdixon

+0

Débarrassez-vous de tout ce crud et utilisez 'snprintf' –

+0

Combien avez-vous appris sur les chaînes de caractères en C jusqu'à maintenant? – immibis

Répondre

-1

Vous devez allouer de l'espace en utilisant un tampon de caractères pour empêcher le strcat de se briser, comme ceci:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
int main(int argc, char *argv[]) { 
    char* path=argv[1]; 
    char oldName[256]; 
    char* newName=argv[3]; 
    char command1[256]; 
    char command2[256]; 
    strcpy(command1, "cd "); 
    strcpy(command2, "ren "); 
    strcpy(oldName, argv[2]); 
    printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 
    strcat(command1,path); 
    printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 
    strcat(oldName," "); 
    strcat(oldName,newName); 
    printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 
    strcat(command2,oldName); 
    printf("\n\n%s\n%s\n%s\n%s\n%s\n",command1,command2,path,oldName,newName); 

    return 0; 
} 
+2

256 octets devraient suffire pour une ligne de commande contenant un chemin et quelques noms de fichiers ... à droite. – Potatoswatter

+0

J'ai beaucoup aidé.Je vous remercie –

+0

@Potatoswatter Je sais que vous êtes sarcastique, mais je tiens à souligner que * les chemins simples * dépassent parfois 256 caractères. C'est un problème réel sur Windows et * nix. – immibis

1

strcat œuvres en copiant octets de la chaîne source à la fin de la chaîne de destination. Le problème est que vos chaînes de destination sont:

  1. chaînes constantes (et ne peuvent pas être en mémoire inscriptible)
  2. Pas assez longtemps pour tenir le résultat entier

Vous devriez probablement créer un char buffer comme char buffer[1024] pour contenir les commandes et utiliser snprintf pour formater les commandes dans le tampon.

+0

Mieux, mais toujours pas assez bon pour une utilisation réelle. Calculez la taille réelle nécessaire avec 'strlen', ou rendez-la ridiculement trop grande, ou faites un vrai traitement de chaîne au lieu de' strcat'. – Potatoswatter

+0

Oui, dans les applications réelles, vous devez gérer des chaînes d'entrée de taille arbitraire. L'utilisation de 'strcat' est dangereuse si vous ne dimensionnez pas correctement les tampons et ceci est une source courante d'exploits de sécurité. L'utilisation de 'snprintf' empêchera le débordement de la mémoire tampon, mais les chaînes de sortie seront tronquées, ce qui n'est pas ce que vous voulez non plus. – EricS

1

strcat s'attend à ce que la destination soit suffisamment grande pour contenir le résultat. Pour quote:

pointeur vers le tableau de destination, qui devrait contenir une chaîne C, et être assez grand pour contenir la chaîne résultante concaténer.