Forum Programmation.c programme c qui émule la commande cat

Posté par  .
Étiquettes : aucune
0
3
déc.
2006
bonsoir tout le monde voila j'essai d'écrire un bête petit programme en c
qui permet d'afficher le contenu d'un fichier (tout comme la commande cat). Je pourrais utiliser les fonctions classiques tellesque fread, feof ...
mais le but c'est d'utiliser les appels systèmes.
je vous soumet mon code; quand je l'exécute j'ai une boucle infinie et ça fait plusieurs heures que je suis dessu car je veux absolument trouver la solution par moi-même. Quelqu'un peut-il me donner un indice pour m'aider un petit peux.
Bien à vous.

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

int main (int argc, char*argv[])
{
int i,byte_lu,d;
char tampon [1024];

for (i=0; i<argc; i++)
{
d= open(argv[i],O_RDONLY);
if(d==-1);
{
printf("these file does not exist\n");
exit(1);
}
else
{
while((byte_lu=read(d,tampon, 1024)), !NULL)
{
printf("%d",d);
close(d);
}
}
}
}
  • # ca serait pas plutot

    Posté par  . Évalué à 2.

    while ((byte_lu=read(d,tampon, 1024)) != NULL)
    à la place de
    while ((byte_lu=read(d,tampon, 1024)), !NULL)

    (attention, ca fait 2 ans que j'ai plus fait de C, et j'ai jamais été vraiment bon :D)

    ps : pourquoi tu exit(1) si un des fichiers n'existe pas ?
    ca veut dire que tu affiches ceux qu'il y a avant, mais pas ceux qu'il y aurait après :/
    • [^] # Re: ca serait pas plutot

      Posté par  (site web personnel) . Évalué à 5.

      > attention, ca fait 2 ans que j'ai plus fait de C, et j'ai jamais été vraiment bon

      Ca s'est vu ;)

      ça ressemble tellement a un exo que je vais pas donner la solution que j'ai sous les yeux. Juste un début de correction à la place.

      Premier problème : il y a un ';' en trop.

      Deuxième problème, il est liè à la condition du "while" : tu utilises la virgule. Mais la virgule, ce n'est jamais qu'un opérateur de séquence, et la valeur de la séquence (c'est ce qui nous intéresse principalement pour ton problème) correspond à la valeur du dernier élément de la séquence : ici c'est "!NULL". Bref, ton while ne termine jamais, comme tu as pu le voir. Faire la négation, comme suggéré, n'est pas la bonne solution... le corps du while ne sera plus jamais exécuté, c'est tout. Bref, un indice quand même : on peut écrire la condition du while sans utiliser la virgule. Autre indice : man read.

      Troisième problème, tu pourras éviter d'afficher le contenu du binaire, ça fera moins mal au terminal. Indice : regarde ta boucle for et la définition de argc/argv dans un bouquin.

      Quatrième problème : si on te demande d'éviter les fputs & co, alors "printf" fait aussi partie du lot (surtout que ce que tu affiches n'est pas ce qui est demandé). Indice : trouver une fonction comme "read" mais qui écrit au lieu de lire... je te préviens, c'est pas évident.

      Du pinaillage : éviter les appels intempestifs à "exit", surtout quand on est dans le "main". Autre pinaillage : plutôt que d'écrire "1024" en dur dans le read, essaye de faire un truc genre : une macro qui vaut 1024 et qui est utilisée à la fois dans la def du tampon et dans le write, et/ou utilise sizeof() dans la read.
      • [^] # Re: ca serait pas plutot

        Posté par  . Évalué à 1.

        scuz moi, j'avais pas lu ton post avant d'écrire les miens, du coup j'lui donne des solutions que tu lui proposais de chercher :/

        PS : j'ai aussi une solution qui marche :)
  • # plop

    Posté par  . Évalué à 1.

    Plusieurs truc me semble bancale.

    D'abord ton ";" dans if(d==-1). Chez moi ça compile pas.
    Ensuite, comme dit plus haut, ton while est pas bon non plus.
    Enfin, si dans ton exos tu DOIS utiliser des appels systems, pourquoi les utiliser pour les read et pas pour les write ? (petit indice, write(0, "plop\n",5); pour afficher plop sur stdout.

    Ah si, encore un truc ... quel interet de printf ton descripteur de fichier ? ce serais pas plutot le contenu de ton buffer que tu afficher ?
    • [^] # Re: plop

      Posté par  . Évalué à 1.

      encore des trucs qui vont pas :

      - utilise des return -1 en cas d'erreur, ça évite d'inclure stdlib.h
      - N'oublie pas de return 0 a la fin de ton int main()
      - N'oublie pas que argv[0] c'est ton programme lui même ...
      • [^] # Re: plop

        Posté par  . Évalué à 1.

        Encore 1 truc ...

        ton close() dans le while() => pas bien non plus !
        Si ton fichier fait plus de 1024, il n'affichera que les premiers 1024 octets ; en gros, ton while ne sert presque a rien.
        • [^] # Re: plop

          Posté par  (site web personnel) . Évalué à 1.

          Ah oui, très juste, je l'avais corrigée celle-là mais j'avais oublié d'en causer.

          Juste pour pinailler : dans le "write(0, ...)" que tu proposes, il y a une erreur. Un indice : grep STDOUT_FILENO /usr/include/unistd.h
          • [^] # Re: plop

            Posté par  . Évalué à 1.

            Effectivement ...
            Apparemment, ça empeche pas le programme plus que ça d'écrire sur stdin :)
        • [^] # Re: plop

          Posté par  . Évalué à 0.

          j'ai une petite question, pour les appels systemes comment détecter la fin d'un fichier passé en argument en ligne de commande, sans faire appel à feof par exemple?
          Bien à vous.
          • [^] # Re: plop

            Posté par  . Évalué à 2.

            T'as pas besoin. Boucle tant que ya des octets à lire ou que t'es pas a la fin du fichier.
            Dans byte_lu, t'as la taille de c'que ton write doit afficher.

            man 2 write
            pour les valeurs de retour.
      • [^] # Re: plop

        Posté par  . Évalué à 2.

        - N'oublie pas de return 0 a la fin de ton int main()

        Pour être plus précis, le return 0; n'est pas obligatoire pour sortir de main en C99, mais c'est une pratique chaudement recommendée quand même ;) (voire return EXIT_SUCCESS;, macro définie dans stdlib.h).

        En passant, je préfère exit (EXIT_FAILURE); à exit(1); (EXIT_FAILURE étant défini dans le même en-tête).

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.