2 votes

changer un programme en c, pour qu'il prenne un argument optionnel en ligne de commande *infile*

J'ai une question à poser à tout le monde... Cela fait quelques jours que je me penche sur la question, que je bricole et que je m'amuse, mais même en faisant cela, je me retrouve avec un tas d'erreurs...

Ce que j'essaie de faire, c'est de prendre le programme ci-dessous et de le modifier de manière à ce qu'il prenne un argument de ligne de commande optionnel. fichier d'entrée . Si fichier d'entrée est donnée, alors la copie fichier d'entrée sur la sortie standard, sinon copier l'entrée standard sur la sortie standard comme auparavant.

L'astuce réside dans le fait que la solution doit utiliser la boucle de copie originale (lignes 9 à 11) dans les deux cas. On ne peut qu'insérer du code et ne pas modifier le code existant. Toute aide serait la bienvenue. Merci beaucoup.

/* $begin cpfile */
include "csapp.h"
int main(int argc, char **argv)
{
    int n;
    rio_t rio;
    char buf[MAXLINE];

    Rio_readinitb(&rio, STDIN_FILENO);                  //line 9
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) //line 10
        Rio_writen(STDOUT_FILENO, buf, n);              //line 11
        /* $end cpfile */
        exit(0);
        /* $begin cpfile */
    }
/* $end cpfile */

5voto

unwind Points 181987

Les programmes C obtiennent des arguments de ligne de commande par l'intermédiaire des deux arguments de la commande main() traditionnellement appelé argc y argv (pour le nombre d'arguments et le vecteur d'arguments, respectivement).

Les arguments ne sont pas "nommés", ce sont juste des chaînes de caractères.

Une solution pour vous pourrait ressembler à ceci :

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fileno;
    /* ... your definitions should remain here, too */

    if(argc > 1)
    {
       /* Assume first argument is filename, and open it. */
       fileno = open(argv[1], O_RDONLY);
       if(fileno < 0)
       {
         printf("Unable to open file, aborting\n");
         return 1;
       }
    }
    else
      fileno = STDIN_FILENO;

  /* ... your code goes here ... */
}

Dans ce cas, il faut bien sûr modifier l'appel à Rio_readinitb() pour utiliser le fileno pour le descripteur de fichier.

Si vous ne pouvez littéralement pas changer cette ligne, pour quelque raison que ce soit ... Je suppose que vous pouvez utiliser le préprocesseur pour que le symbole évalue le nouveau nom de la variable :

#undef  STDIN_FILENO
#define STDIN_FILENO fileno

Ce n'est évidemment pas très joli, mais cela devrait fonctionner.

Assurez-vous de placer ces macros de préprocesseur après el fileno = STDIN_FILENO; ligne.

1voto

qrdl Points 17813

Si STDIN_FILENO ne peut pas être réaffecté, il semble que ce soit une tâche à confier à l freopen() :

freopen(argv[1], "r", stdin);

1voto

skwllsp Points 9661

Vous pouvez insérer dup2 avant les lignes 9 à 11 et il semble que vous n'aurez pas besoin de modifier le code sur les lignes 9 à 11. Voici un exemple.

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>

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

    int file_handle;
    int dup2_res;
    if (argc == 2) {
        file_handle = open(argv[1], O_RDONLY);
        dup2_res = dup2 (file_handle, STDIN_FILENO);
    }

    char buffer[100];
    ssize_t read_bytes = 1;
    while (read_bytes)
    {
        read_bytes = read(STDIN_FILENO, &buffer, sizeof(buffer) );
        buffer[read_bytes] = 0;
        printf("%s", buffer);
    }
    close(file_handle);

    return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X