J'écrivais un programme qui pouvait passer un argument de ligne de commande dans un programme c. Les commandes linux sont stockées dans un fichier appelé "sample-input". Il ne contient que cp file1 dest1 ou mv file2 dest2. Mon problème est lorsque je tokenise la chaîne dans le fichier. Il semble qu'il ne lise que la première ligne du fichier. Voici mon code. Quelqu'un peut-il m'aider, s'il vous plaît ?

error message i got (after edit):

    temp1/f4.txt
 temp1/f5.txt
 temp1/f6.txt
-temp1/f7.c
+temp1/f8.c
+temp2/f1.txt
 temp2/f2.c
+temp2/f3.txt
 temp2/f4.txt
+temp2/f5.txt
 temp2/f6.txt
 temp2/f9.c
Test Result: [Failed]


    my sample-input
    cp temp1/f1.txt              temp2/
    mv temp1/f2.c                           temp2/
    cp temp1/f3.txt                temp2/
    cp temp1/f4.txt                temp2/
    cp temp1/f5.txt                temp2/
    cp temp1/f6.txt                 temp2/
    mv temp1/f7.c                   temp1/f8.c
    mv temp1/f9.c                   temp2/
    cp temp1/f1.txt              temp1/f1a.txt

Mon code actuel.

   /* Your code goes here */

#define _GNU_SOURCE
#include <string.h>
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


int main(int argc, char* argv[])
{
    FILE* fp;
    fp = fopen("sample-input", "r");

    if (fp == NULL) {
        fprintf(stderr, "An error has occured1\n");
        exit(1);
    }
    if (argc != 2) {
        fprintf(stderr, "argc=%d\n", argc);
        fprintf(stderr, "An error has occured2 \n");
        exit(1);
    }
    else if (argc == 2) {
        char ag[1024];

        while (fgets(ag, 1024, fp) != NULL)
        {
            fgets(ag, 1024, fp);

            char* array[4];
            int i = 0;
            char* token = strtok(ag, " \t\n");

            while (token != NULL) {

                array[i] = token;
                i++;
                token = strtok(NULL, " \t\n");
            }
            array[i] = NULL;
            int r = fork();

            if (r == 0) {
                execvp(array[0], array);
            }
            else if (r < 0) {

                fprintf(stderr, "An error an occoured\n");
                exit(1);

            }
            else {

                wait(NULL);

            }


        }




    }
    return 0;
}
1
De Zeng 21 févr. 2020 à 21:04

1 réponse

Meilleure réponse

Cette

execvp(array[i], array);

Doit être

execvp(array[0], array);

Car le premier argument sera le nom de fichier de l'exécutable. Et vous devriez gérer le cas, que execvp() échoue, correctement en émettant un message et en quittant (!).

perror("execvp");
exit(EXIT_FAILURE);

De plus, vous devez terminer par NULL votre vecteur d'argument en définissant

array[i] = NULL;

Après votre boucle while. Et mieux vaut ajouter une vérification, qui sort de la boucle après avoir analysé trois arguments, sinon array peut déborder (écriture hors limites conduisant à un comportement indéfini).

Un autre problème est votre boucle de lecture

while (fgets(ag, 1024, fp) != NULL) {
        fgets(ag, 1024, fp);
}

Cela lira quelque peu votre fichier de manière sauvage et vous laissera avec la dernière ou la dernière ligne précédente. Vous devez mettre la ligne de gestion à l'intérieur de la boucle :

while (fgets(ag, 1024, fp) != NULL) {
    // Parse arguments and fork/exec here inside
}

Selon votre fichier d'entrée, il semble que les tabulateurs puissent également être un séparateur d'arguments, utilisez donc

strtok(ag, " \t\n");

Et

strtok(NULL, " \t\n");
2
Ctx 21 févr. 2020 à 18:23