Essayez d'utiliser execvp() en C avec la saisie de l'utilisateur sous unix
Je suis en train de faire un programme qui demande à l'utilisateur pour une commande, puis utiliser exec pour exécuter cette commande.
Par exemple, si ils m'ont donné "ls-la", je serais pour l'exécution de cette commande. J'ai essayé le code suivant:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int ret, num_args;
printf("Enter number of arguments (Example: \"ls -la\" has 1 argument): ");
scanf("%d", &num_args);
char *cmd[num_args];
printf("Enter command name: ");
scanf("%s", &cmd[0]);
int i;
for (i = 0; i < num_args; i++)
{
printf("Enter parameter: ");
scanf("%s", &cmd[i]);
}
execvp(cmd[0], cmd);
}
Cependant, quand j'ai essayé d'exécution suivant il m'a donné un "segmentation fault"
$ ./a.out
Enter number of arguments (Example: "ls -la" has 1 argument): 2
Enter command name: ls
Enter parameter: -la
Enter parameter: .
Segmentation fault
$
Des idées?
OriginalL'auteur | 2009-08-24
Vous devez vous connecter pour publier un commentaire.
Si votre application prend en charge, vous devez utiliser le plus sûr
getline()
plutôt surscanf()
oufgets()
.getline()
permettra de gérer en toute sécurité les longues lignes et des caractères NULL. Il va allouer suffisamment de mémoire pour s'adapter à l'ensemble de la ligne.getline()
peut allouer de la mémoire de sorte que vous aurez à le libérer vous-même plus tard.Ici est la la glibc
getline()
de la documentation.Ici est une modification rapide à utiliser getline (Il a encore besoin de travail, la vérification des erreurs et je n'ai pas entièrement vérifié l'exactitude encore):
getline
est une distribution GNU fonction en C: gnu.org/s/libc/manual/html_node/Line-Input.htmlQuel compilateur et quel Système d'Exploitation?
i686-apple-darwin9-gcc-4.0.1 (OS X 10.5.8)
Est-ce une erreur de l'éditeur de liens, ou une déclaration implicite d'avertissement?
OriginalL'auteur Karl Voigtland
Vous avez besoin d'allouer de la mémoire pour vos chaînes. La ligne suivante n'alloue
num_args
valeur des pointeurs verschar
:Tout d'abord, vous allez recevoir
num_args + 1
cordes (n'oubliez pas que la commande elle-même estcmd[0]
). Le plus simple est d'allouer de manière statique la mémoire comme un tableau de caractères tampons:Cependant, maintenant, vous ne pouvez pas utiliser
scanf
à lire en ligne, car l'utilisateur pourrait entrer une chaîne de caractères qui est plus long que votre personnage tampon. Au lieu de cela, vous aurez à utiliserfgets
, ce qui peut limiter le nombre de caractères que l'utilisateur peut saisir:Gardez à l'esprit que
fgets
lit aussi des caractères de saut de ligne, alors assurez-vous de supprimer toutes les égarés qui se présentent (mais ne présumez pas qu'ils sont là).Vérifiez votre code; j'ai écrit un petit programme de test et il a compilé bien pour moi.
Oups, j'ai oublié un point-virgule à la
MAX_LEN = 512
ligne. Fixe maintenant.scanf
pouvez également limiter le nombre de caractères que l'utilisateur peut saisir utilisation"%511s"
si votre tampon est de taille 512, comme dans votre exemple.Oh, et si vous faites cela, vous ne pouvez pas passer directement
cmd
àexecvp
plus - il a besoin d'un tableau de pointeurs sur char (terminé par un pointeur NULL entrée), pas un tableau de tableaux de char (ce qui est un bon exemple d'un cas dans lequel ils sont pas l'équivalent).OriginalL'auteur Andrew Keeton
Aussi, vous en avez besoin plus d'entrée dans le
argv
vous passez àexecvp
, qui doit être(char *)NULL
pour laisser savoir qu'il est arrivé à la fin de la liste.OriginalL'auteur hobbs
Vous n'avez pas alloué de la mémoire pour les chaînes pointées par le cmd tableau.
Rechercher malloc/free, et assurez-vous que chaque pointeur "cmd" est alloué suffisamment d'espace.
OriginalL'auteur Paul Tomblin
Prendre un coup d'oeil à la page de man pour le scanf(). Une des plus belles choses qu'il peut faire est d'allouer automatiquement la chaîne de tampons à la volée, vous devez fournir un pointeur vers une chaîne de caractères au lieu de simplement en passant la chaîne d'approvisionnement et l' %format.
Alors vous n'avez pas besoin de s'embêter avec preallocating, n'a pas besoin de s'embêter avec des dépassements de tampon, etc. N'oubliez pas de free() une fois que vous avez terminé avec elle.
%as
' spécification est pas C standard de comportement utile si elle peut être.OriginalL'auteur KFro