Atteindre EOF avec fgets
Je suis en train d'écrire une fonction qui effectuer quelques authentifications actions. J'ai un fichier avec tous les user_id:password:flag
couples structuré comme ceci:
Users.txt
user_123:a1b2:0 user_124:a2b1:1 user_125:a2b2:2
C'est le code:
int main(){
/*...*/
/*user_id, password retrieving*/
USRPSW* p = malloc(sizeof(USRPSW));
if(p == NULL){
fprintf(stderr, "Dynamic alloc error\n");
exit(EXIT_FAILURE);
}
memset((void*)p, 0, sizeof(USRPSW));
if(usr_psw_read(acc_sock_ds, p->user_id, USR_SIZE) <= 0){
printf("Failed read: connection with %s aborted.\n",
inet_ntoa(client_addr.sin_addr));
close(acc_sock_ds);
continue;
}
if(usr_psw_read(acc_sock_ds, p->password, PSW_SIZE) <= 0){
printf("Failed read: connection with %s aborted.\n",
inet_ntoa(client_addr.sin_addr));
close(acc_sock_ds);
continue;
}
/*Authentication through user_id, password*/
FILE *fd;
fd = fopen(USERSFILE, "r");
if(fd == NULL){
fprintf(stderr, "Users file opening error\n");
exit(EXIT_FAILURE);
}
char *usr_psw_line = malloc(USR_SIZE+PSW_SIZE+3+1);
if(usr_psw_line == NULL){
fprintf(stderr, "Dynamic alloc error\n");
exit(EXIT_FAILURE);
}
while(1){
memset((void*)usr_psw_line, 0, sizeof(USR_SIZE+PSW_SIZE+3+1));
fgets(usr_psw_line, USR_SIZE+PSW_SIZE+3+1, fd);
printf("%s\n", usr_psw_line);
fseek(fd, 1, SEEK_CUR);
/*EOF management*/
/*usr_id - password matching checking */
}
/*...*/
}
Comment puis-je gérer les expressions du FOLKLORE d'atteindre? J'ai vu que lorsque EOF est atteint fgets
ne modifie plus le usr_psw_line mais ni renvoie un pointeur NULL. Si EOF est atteint, cela signifie qu'aucun match sont trouvés dans le fichier et la boucle pauses.
Quelqu'un peut-il me donner quelques conseils ou suggestions?
- Si la fin de fichier est atteinte sans la lecture de tout les personnages,
fgets
est obligé de retournerNULL
. De toute façon, vous pouvez vérifierfeof(fd)
aprèsfgets
n'ai pas lu quoi que ce soit. - J'ai peur que les expressions du FOLKLORE n'est pas définie. Je ne écrire un fichier avec des enregistrements à l'intérieur.Je doit également définir explicitement les expressions du FOLKLORE? Comment faites-vous cela?
- N'est-il pas atteint la fin du fichier pendant la lecture? Vous ne définissez pas EOF si la fin du fichier est atteinte, la prochaine tentative de lecture de il va mettre le drapeau en
*fd
, doncfeof(fd)
sera alors retourner vrai si tout fonctionne comme il se doit. Si tout ne fonctionne pas comme il devrait, hmmm. EOF
est un état, pas une partie du flux. Imaginez le flux de l'eau provenant d'un robinet. Quand vous ouvrez le robinet jusqu'à ce qu'il épuise obtenez-vous plus de l'eau (dans une autre couleur?) au signal, il n'y a plus d'eau?- Pour plausible, la taille de la table, vous feriez mieux de ne pas utiliser
malloc()
de l'information — juste de l'utilisation habituelle des tableaux. - pourriez-vous me dire pourquoi?
- Sauf si vous allez être en utilisant plus de, oh, 8 Ko de données, vous pouvez ainsi éviter la surcharge de
malloc()
et de la possibilité de fuites en utilisantchar usr_psw_line[USR_SIZE+PSW_SIZE+3+1];
au lieu de l'allocation dynamique de la mémoire. Dansmain()
, vous n'allez pas être de retour l'allocation d'un tableau, ce qui n'est pas une raison pour faire la répartition de ce temps — dans une fonction, il pourrait être une bonne raison. - Il est intéressant de noter que c'est la meilleure définition pour
EOF
j'ai jamais entendu.
Vous devez vous connecter pour publier un commentaire.
fgets()
retourner un pointeur null quand il atteint la fin de fichier ou une condition d'erreur.(
EOF
est une macro qui spécifie la valeur renvoyée par certains autres fonctions dans des conditions similaires; ce n'est pas seulement une abréviation de l'expression "fin de fichier".)Vous êtes ignorant le résultat retourné par
fgets()
. Ne pas le faire.Noter que la simple vérification
feof(fd)
de ne pas faire ce que vous voulez.feof()
retourne un résultat vrai si vous avez atteint la fin du fichier. Si vous rencontrez une erreur au lieu de cela,feof()
renvoie toujours faux, et vous avez vous-même une boucle infinie si vous utilisezfeof()
de décider quand vous avez terminé. Et il ne renvoie pas vrai jusqu'à ce que après vous ai pas réussi à lire l'entrée.Plus C d'entrée fonctions renvoient une valeur spéciale pour indiquer qu'il n'y a plus rien à lire. Pour
fgets()
c'estNULL
, pourfgetc()
c'estEOF
, et ainsi de suite. Si vous le souhaitez, vous pouvez appelerfeof()
et/ouferror()
par la suite pour déterminer pourquoi il n'y a rien de plus à lire.Vous pourriez vouloir essayer quelque chose comme ceci dans votre boucle:
Avec le code supplémentaire, la boucle sera résiliée si
fgets
renvoie la valeur NULL (pas plus de données à lire) ou si vous êtes de lire les expressions du FOLKLORE marque ou avait aucune erreur sur le fichier. Je suis sûr que c'est exagéré, mais ces tests ont toujours travaillé pour moi.while (fgets(usr_psw_line, sizeof(usr_psw_line), fd) != 0)
pour la condition de la boucle. Il n'y a vraiment pas besoin de beaucoup à zéro de la mémoire avant de le lire. Et il n'y a aucun avantage à l'essai avecferror()
oufeof()
là (depuis qu'ils avaient seulement d'évaluer la valeur vrai si le test sur le retour defgets()
retourne NULL; par conséquent, ils n'ont jamais cause de la boucle de sortie).ferror()
retourne l'état de l'indicateur d'erreur qui peut avoir été mis en avant lafgets()
appel.fgets()
n'est pas évident que le drapeau alorsfgets()
peut retourner une valeur non-NULL
encoreferror()
renvoie la valeur true.fgets()
est appelé,fgets()
doit échouer. Cependant, je ne peux pas vraiment trouver de verbiage dans la norme qui indique que, même si je serais étonné de trouver une mise en œuvre qui ne se comportent pas comme ça. Si vous le suivi de l'état de flux, vous n'allez pas l'utiliser après un échec, sauf si vous utilisezclearerr()
. Il y a un peu plausible bord de cas disponibles. Les testsfeof()
est inutile. Je m'en tiens à mon observation pour une utilisation quotidienne. Si j'étais inquiet au sujet de l'état d'erreur du flux, je ne l'utiliseraisferror()
à l'entrée de la fonction.feof()
, obscureness et le code de bonne permettrait de testerferror()
, mais elle a été le only qui a attiré mon oeil.fgets()
ne retourne pas automatiquementNULL
si le flux de indicateur d'erreur est réglé, mais sera de retourNULL
est une erreur de lecture se produit (ce qui a pour effet de bord de la définition de la indicateur d'erreur).