Quel est le bug ?

Quel est le bug ? - C - Programmation

Marsh Posté le 29-03-2006 à 02:13:12    

Bonjour,
En testant ce petit programme qui est l'équivalent du ls sous linux avec différentes options, je me suis appercu qu'il affiche un . (point) en trop avant le listing.
 
Quelqu'un pourait me dire pourquoi ? comment ne plus l'afficher ?
 
Merci par avance
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#define  space 100
 
/* Déclaration des différentes options de my_ls */
struct options{
  int R; /* Affichage récursif du contenu des dossiers */
  int n; /* Affichage numéric UIDs et GIDs*/
  int l; /* Affichage listé en détails (droits, groupe, date, ...) */
  int i; /* Affiche l'index d'entrée de chaque fichier */
  int s; /* Affiche la taille de chaque fichier */
  int d; /* Affichage le répertoire d'entrée seul */
  int a; /* Affichage de tous les fichiers y compris les . */
};
 
/* Revoie la dernière composante d'un chemin
   (ce qui est passé après le dernier slash, s'il y en a un) */
char *dirname(char *name){
  int i=strlen(name);
  while(i>=0 && name[i]!='/') i--;
  return name+i+1;
}
 
/* Affichage du fichier selon l'option passée
   Récuperation des caracteristiques des fichiers */
int printfile(char *namefile, struct options option){
  struct stat s;
  int i, j;  
  char plug[space+1];  
  if (lstat(namefile, &s)){
    fprintf(stderr,"%s :", namefile);
    perror("lstat()" );
    return(2);
  }
  if (option.i)
    printf("%7d ",(int) s.st_ino);
  if (option.s)
    printf("%3d ", (int)s.st_blocks);
 
  if (option.n || option.l){
    char d[]="?rwxrwxrwx";
    int flag[]={S_IRUSR,S_IWUSR,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,
         S_IWOTH,S_IXOTH,S_ISUID,S_ISGID,S_ISVTX};
   /* respectivement :     le propriétaire a le droit de lecture, d'écriture,
   d'exécution, le groupe a le droit de lecture, d'écriture, d'exécution,
   les autres ont le droit de lecture, d'écriture, d'exécution,
   bit Set-UID, bit Set-Gid, bit "sticky" */
   
    switch (s.st_mode & S_IFMT){ /* & masque du type de fichier /*
    case S_IFLNK: d[0]='l'; break; /* fichier lien symbolique */
    case S_IFDIR: d[0]='d'; break; /* s'il s'agit d'un directory */
    case S_IFREG: d[0]='-'; break; /* fichier normal */
    }
    for (i=0;i<9;i++)
      if (!(s.st_mode & flag[i])) d[i+1]='-';
    for (i=0; i<3;i++)
      if ((s.st_mode & flag[9+i])) d[3*i+3]='s';
    printf("%s %3d ", d, (int) s.st_nlink);
    struct passwd *pwd = getpwuid(s.st_uid);
    if (pwd && !option.n) printf("%8s ", pwd->pw_name);
    else printf("%4d ", (int) s.st_uid);
    struct group *grp = getgrgid(s.st_gid);
    if (grp && !option.n) printf("%8s ", grp->gr_name);
    else  printf("%8d ", (int) s.st_gid);
    printf("%7d ", (int) s.st_size);
    printf("%.24s ", ctime(&(s.st_mtime)));
  }
  printf("%s", option.d?namefile:dirname(namefile));
  if (S_ISLNK(s.st_mode)){
    if ((j=readlink(namefile, plug, space))==-1){
      perror("readlink()" );
    }else{
      plug[j]=0;
      printf(" -> %s ", plug);
    }
  }
  printf("\n" );
  return(0);
}        
 
/* Affichage d'un fichier ou repertoire.
   Pour un fichier, on l'affiche simplement
   Pour un repertoire, on fait la descente récursive si -R */
int printdirectory(char *directory, struct options option){
  struct dirent **l;
  struct stat s;
  char list[space];    
  int i,j,tot=0;
  printf("%s:\n", directory);
  if ((i=scandir(directory, &l, NULL, alphasort))==-1){
    perror("scandir()" );
    return(1);
  }
  if (option.s || option.l){
    for (j=0; j<i; j++){
      if (l[j]->d_name[0] == '.' && option.a==0)
    continue;
      snprintf(list, space, "%s/%s",directory, l[j]->d_name);    
      if (lstat(list,&s)){
    fprintf(stderr,"%s:", list);
    perror("lstat()" );
    continue;
      }
      tot += s.st_blocks;
    }
    printf("Total: %d\n", tot);
  }      
 
  for (j=0;j<i;j++){
    if ((l[j]->d_name)[0] == '.' && option.a==0)
      continue;
    snprintf(list, space, "%s/%s",directory, l[j]->d_name);    
    if (lstat(list,&s)){
      fprintf(stderr,"%s: ", list);
      perror("lstat()" );
      continue;
    }
    printfile(list, option);
  }
  printf("\n" );
  for (j=0; j<i; j++){
    snprintf(list, space, "%s/%s",directory, l[j]->d_name);    
    if (lstat(list,&s)){
      fprintf(stderr,"%s: ", list);
      perror("lstat()" );
    }else
      if (S_ISDIR(s.st_mode) && strcmp(l[j]->d_name,"." )
      && strcmp(l[j]->d_name,".." ) && option.R==1){
    printdirectory(list, option);
      }
    free(l[j]);
  }  
  free(l);
  return(0);
}
 
int main(int argc, char *argv[]){
  struct stat s;
  int i;
  struct options option={0,0,0,0,0,0,0};
  char opt;
  opterr=0;
  while ((opt=getopt(argc, argv, "Rlnisda" )) != -1){
    switch (opt){
    case 'l': option.l=1; break;
    case 'n': option.n=1; break;
    case 'R': option.R=1; break;
    case 'i': option.i=1; break;
    case 's': option.s=1; break;
    case 'd': option.d=1; break;
    case 'a': option.a=1; break;
/* Afficher que l'option taper n'est pas utilisée */
    default: fprintf(stderr,"option -%c non utilisee\n",opt);
    }
  }
  if ((argc-optind)==0)
    {
      if (option.d) printfile(".",option);
      else printdirectory(".", option);
    }
  for (i=optind; i<argc; i++){
    if (lstat(argv[i], &s)){
      fprintf(stderr,"%s: ", argv[i]);
      perror("lstat()" );
      continue;
    }
    if (!S_ISDIR(s.st_mode) || option.d){
      printfile(argv[i],option);
      printf("\n" );
    }
    else{
      printdirectory(argv[i], option);
    }    
  }
  return(0);
}

Reply

Marsh Posté le 29-03-2006 à 02:13:12   

Reply

Marsh Posté le 29-03-2006 à 09:54:41    

Flemme de lire un programme non formaté avec des smilies partout, merci d'utiliser les balises [cpp][/cpp].
 
Et pour le "point" supplémentaire, c'est peut-être pour désigner le répertoire courant.

Reply

Marsh Posté le 29-03-2006 à 10:39:38    

il y a plein d'erreurs de syntaxe
 

Citation :

ls.c: In function `printfile':
ls.c:40: error: parse error before ';' token
ls.c:57:65: warning: "/*" within comment
ls.c:58:36: warning: "/*" within comment
ls.c:79: error: parse error before ';' token
ls.c:85: error: parse error before ';' token
ls.c: In function `printdirectory':
ls.c:99: error: parse error before ';' token
ls.c:109: error: parse error before ';' token
ls.c:123: error: parse error before ';' token
ls.c:128: error: parse error before ';' token
ls.c:133: error: parse error before ';' token
ls.c:135: error: parse error before ';' token
ls.c: At top level:
ls.c:141: warning: type defaults to `int' in declaration of `free'
ls.c:141: warning: parameter names (without types) in function declaration
ls.c:141: error: conflicting types for 'free'
/usr/include/stdlib.h:80: error: previous declaration of 'free' was here
ls.c:141: error: conflicting types for 'free'
/usr/include/stdlib.h:80: error: previous declaration of 'free' was here
ls.c:141: warning: data definition has no type or storage class
ls.c:142: error: parse error before "return"

Reply

Marsh Posté le 29-03-2006 à 15:03:17    

mayapour a écrit :

En testant ce petit programme qui est l'équivalent du ls sous linux avec différentes options, je me suis appercu qu'il affiche un . (point) en trop avant le listing.


Pas très clair comme code...


Project   : forum
Compiler  : GNU GCC Compiler (called directly)
Directory : /home/edelahaye/dev-c/forum/
--------------------------------------------------------------------------------
Switching to target: default
Compiling: ../main.c
../main.c:27: warning: no previous prototype for 'dirname'
../main.c:35: warning: no previous prototype for 'printfile'
../main.c:58:65: warning: "/*" within comment
../main.c:59:36: warning: "/*" within comment
../main.c:93: warning: no previous prototype for 'printdirectory'
../main.c: In function 'main':
../main.c:167: warning: passing argument 1 of 'printfile' discards qualifiers from pointer target type
../main.c:168: warning: passing argument 1 of 'printdirectory' discards qualifiers from pointer target type
../main.c:185:2: warning: no newline at end of file
../main.c: In function 'printdirectory':
../main.c:136: warning: will never be executed
../main.c:136: warning: will never be executed
../main.c:136: warning: will never be executed
../main.c:137: warning: will never be executed
../main.c:137: warning: will never be executed
Linking console executable: /home/edelahaye/dev-c/forum/forum
Process terminated with status 0 (0 minutes, 7 seconds)
0 errors, 13 warnings
 


Sinon, le '.' est normal. Il désigne le répertoire courant.


Message édité par Emmanuel Delahaye le 29-03-2006 à 15:24:05

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed