Dans le cadre d'un devoir d'une de mes classes, je dois écrire un programme en C pour dupliquer les résultats de la commande ls -al. J'ai lu le matériel nécessaire mais je n'obtiens toujours pas le bon résultat. Voici mon code jusqu'à présent, il est uniquement censé imprimer la taille et le nom du fichier, mais les tailles de fichier que son impression n'est pas correcte.
Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, char* argv[])
{
DIR *mydir;
struct dirent *myfile;
struct stat mystat;
mydir = opendir(argv[1]);
while((myfile = readdir(mydir)) != NULL)
{
stat(myfile->d_name, &mystat);
printf("%d",mystat.st_size);
printf(" %s\n", myfile->d_name);
}
closedir(mydir);
}
Voici mes résultats après avoir exécuté le code:
[root@localhost ~]# ./a.out Downloads
4096 ..
4096 hw22.c
4096 ankur.txt
4096 .
4096 destination.txt
Voici les bonnes tailles:
[root@localhost ~]# ls -al Downloads
total 20
drwxr-xr-x. 2 root root 4096 Nov 26 01:35 .
dr-xr-x---. 24 root root 4096 Nov 26 01:29 ..
-rw-r--r--. 1 root root 27 Nov 21 06:32 ankur.txt
-rw-r--r--. 1 root root 38 Nov 21 06:50 destination.txt
-rw-r--r--. 1 root root 1139 Nov 25 23:38 hw22.c
Quelqu'un peut-il s'il vous plaît signaler mon erreur.
Merci,
Ankur
myfile->d_name
Est le nom de fichier et non le chemin d'accès, vous devez donc d'abord ajouter le nom de fichier au répertoire "Downloads/file.txt"
, S'il ne s'agit pas du répertoire de travail:
char buf[512];
while((myfile = readdir(mydir)) != NULL)
{
sprintf(buf, "%s/%s", argv[1], myfile->d_name);
stat(buf, &mystat);
....
Quant à savoir pourquoi il affiche 4096
Qui est la taille des liens .
Et ..
Du dernier appel à stat()
.
Remarque: vous devez allouer un tampon suffisamment grand pour contenir le nom du répertoire, le nom du fichier l'octet NULL
et le séparateur, quelque chose comme ça
strlen(argv[1]) + NAME_MAX + 2;
Ceci est le code final que j'ai pu travailler pour toute personne intéressée. Il imprime les tailles de fichier correctes. Le crédit revient au demandeur et au multiplexeur pour avoir répondu, simplement en assemblant le code. L'entrée pour laquelle j'ai pu travailler est "./main". .
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, char* argv[])
{
DIR *mydir;
struct dirent *myfile;
struct stat mystat;
char buf[512];
mydir = opendir(argv[1]);
while((myfile = readdir(mydir)) != NULL)
{
sprintf(buf, "%s/%s", argv[1], myfile->d_name);
stat(buf, &mystat);
printf("%zu",mystat.st_size);
printf(" %s\n", myfile->d_name);
}
closedir(mydir);
}
Je pense que vous constaterez que si vous ./a.out .
vous obtiendrez le comportement que vous attendez.
Vous avez un bug légèrement subtil, observable si vous examinez le code retour de votre appel à stat(2)
.
L'erreur fondamentale: les dirent
s retournés par readdir(2)
(les myfile
dans votre code) auront un d_name
par rapport à mydir
. Votre code stat
..
d'abord, réussira, et donc mystat
contiendra des données valides pour ..
, puis tous les appels suivants à stat(2)
échouera, renvoyant -1
, que vous ne vérifiez pas, donc mystat
ne sera pas modifié, et vous imprimerez le st_size
pour l'ancienne valeur, c'est-à-dire celle de ..
.
Le problème est que lorsque vous stat("ankur.txt", &mystat)
, vous ne travaillez pas sur le fichier "Downloads/ankur.txt"
. Très probablement, la stat()
échoue; alternativement, il fait rapport sur un fichier différent.
Par conséquent, vous devez vérifier si votre système prend en charge fstatat()
- nouveau dans POSIX 2008 - ou arranger pour préfixer le nom du fichier avec le nom du répertoire.