Je veux écrire un programme C qui prend comme argument le chemin d'accès à un dossier et affiche certaines informations sur les fichiers qu'il contient.
Jusqu'à présent, j'ai écrit ceci: P>
#include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <stdio.h> #include <string.h> int main(int argc, char** argv){ char* dir_path = argv[1]; char* dir_path_bar = strcat(dir_path, "/"); DIR* dir = opendir(dir_path); for(struct dirent* entry = readdir(dir); entry != NULL; entry = readdir(dir)){ printf("Next entry is %s\n", entry->d_name); char* entry_path = strcat(dir_path_bar, entry->d_name); printf("%s\n", entry_path); struct stat buf; stat(entry_path, &buf); printf("Its inode number is %s\n", entry->d_ino); printf("Its inode number is %s\n", buf.st_ino); printf("Its uid is %s\n", buf.st_uid); printf("Its size is %s bytes\n", buf.st_size); }; closedir(dir); }
3 Réponses :
Deux problèmes:
Vous êtes Ajout em> en continu à l'entrée ( Impression également des valeurs entier utilisant Vous pouvez plutôt utiliser un tampon temporaire et le transmettre à J'ai également ajouté une vérification des erreurs. p> p> argv [1] code>) argument qui est un comportement indéfini. Vous ne pouvez pas ajouter aux chaînes de
argv code>. P> li>
% s code> non défini aussi.
% code> s attend un argument
char * code>, mais vous vouliez imprimer des valeurs entières. P> li>
ul>
stat (2) code> : p>
J'avais à nouveau UV pour l'utilisation sage de (uintMax_t) code> avec
entrée-> d_ino code> (comme de même 3x endroits.)
J'ai nettoyé des commentaires antérieurs. Avec snaprintf () code> détection d'erreur robuste utilise
int y = snaprintf (p, sz, ...); si (y <0 || y> = n)) erreur (); code> votre
snprintf (...)> = (int) sz) code> est ok mais n'atteint pas les rares Erreur de codage, ni la situation rare où
(int) sz code> perdre des informations.
En général, une bonne manipulation des erreurs permet malheureusement plus longtemps que le code attrayant. Dommage que cette réponse n'a pas été acceptée.
Je suis d'accord (note que y <0 code> n'est pas dans la norme C mais POSIX). Mais je ne comprends pas pourquoi
(int) sz code> troncature serait un problème car SnPRINTF renvoie un
int code>. Casting Valeur de retour de Snprintf à
Taille_T Code> a le problème opposé (par exemple, SNPRINTF renvoie une valeur négative).
Seulement s'adressant à C, pas POSIX: "Ainsi, la production terminée nulle a été complètement écrite si et uniquement si la valeur renvoyée est non négative et inférieure à n code>." C11 §7.21.6.5 3. Test de négatif
Y code> est i> en raison de la norme C. Dans les cas extrêmes, si
sz code> était
int_max + 1 code>,
(int) sz code> peut devenir une étiquette négative et incorrecte
sprintf () < / code> un échec. "La valeur de retour de Snprintf à Taille_T a le problème opposé (par exemple, SnPrintf renvoie une valeur négative)" n'est pas applicable car il est après le
y <0 code> et donc le
y> n Code> Cast / Comparer n'est pas exécuté avec négatif
Y code>.
Laissez-nous Continuez cette discussion dans le chat .
J'ai détaillé de certaines réflexions sur snaprintf () code> en fonction de notre discussion.
Comme d'autres personnes ont mentionné, vous ne pouvez pas ajouter à Voici votre code avec les bogues annotés et fixes [Utilisation argv [1] code>. Vous ne pouvez pas continuer à l'ajouter à l'intérieur de la boucle. Et, vous ne pouvez pas utiliser
% s code> pour produire des numéros de sortie.
#if 0 code> pour afficher l'ancien code ]: p>
"Celles-ci ont besoin% d /% ld /% lld" -> qui n'est pas clair comme .d_ino, .st_ino, .st_uid, .st_size code> ne sont certainement pas
long, long, int, long, int, long code> Réf . Certains d'entre eux sont des membres non signés i> également.
Non indiqué dans les 2 autres réponses précédentes est une bonne évitant de la copie excessive.
Lors de la formulation du entrée_Path code>, seule l'entrée elle-même doit être écrasée, et non la chaîne entière. Cela devient précieux avec une longue chaîne de répertoires pré-fixes. P>
Vous appelez
strcat code> sur l'un des éléments code> argv code>. Comment savez-vous que le pointeur a suffisamment d'espace pour cela? Au lieu de cela, créez un tampon local et copier
argv [1] code> dans cela.