Problème de lecture dans un fichier (C, unistd.h)
Bonjour à tous, et merci d'avoir pris le temps d'ouvrir mon post.
Voici mon problème :
J'écris une fonction qui récupère le contenu d'un champ dans un fichier.
J'ai d'abord besoin de positionner la tête de lecture à un endroit précis.
Cet endroit est caractérisé par les deux premiers caractères de la ligne qui le contient (le chiffre 1 suivi d'une tabulation).
Pour localiser cette ligne, je lis le fichier jusqu'à atteindre ces deux caractères.
J'utilise une variable que j'appelle INIT (char INIT[2] ;), et l'appel système read (de la librairie unistd.h).
La lecture est conditionnelle : tant que INIT est différent des deux caractères à localiser, la lecture se poursuit.
while (strcmp(INIT, "1\t") != 0)
{
NEXT_LINE(FD) ;
SAFE_READ_2 ;
}
La fonction auxiliaire NEXT_LINE me permet de passer d'une ligne à l'autre dans le fichier.
SAFE_READ_2 est une macro représentant la lecture de deux caractères :
# define SAFE_READ_2 {if (read(FD, INIT, 2) != 2*sizeof(char)) {perror("Unable to read file") ; errno = 0 ; exit(EXIT_FAILURE) ;}}.
Mon problème est le suivant : je déclare INIT comme une variable locale sur un espace mémoire de deux caractères, et à l'appel de read, j'indique donc une lecture de deux caractères dans le fichier.
Pas de problème lors de la compilation ; mais à l'éxécution, ma variable INIT contient 6 caractères.
Après quelques tests, j'ai observé qu'avant tout appel de read, ma variable INIT, malgré sa déclaration (char INIT[2] ;), est déjà représentée en mémoire par un espace de 6 caractères.
Je sèche complètement. Quelqu'un aurait-il une idée ?
En vous remerciant de m'avoir lu,
Scott.
Ci-joint, le code de la fonction en question :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| char * EXTRACT_FIELD(int LINE, int FIELD, char * PATHNAME)
/*
* Renvoi le contenu du champs numéroté par FIELD de la ligne numérotée par LINE
* dans le fichier accessible par PATHNAME.
*
*/
{
char INIT[2], CURRENT[1], * CONTENT ;
int i, FD ;
string_d * STRING ;
printf("%s\n", INIT) ;
FD = open(PATHNAME, O_RDONLY) ;
if (FD <= 0)
{
perror("[EXTRACT_FIELD] : Unable to open file") ;
errno = 0 ;
exit(EXIT_FAILURE) ;
}
SAFE_READ_2 ;
while (strcmp(INIT, "1\t") != 0) // Positionnement sur le premier
{ // champ de la première ligne.
NEXT_LINE(FD) ;
SAFE_READ_2 ;
}
for (i = LINE ; i > 0 ; --i) // Positionnement sur la ligne
NEXT_LINE(FD) ; // numérotée par l'entier LINE.
for (i = FIELD ; i > 0 ; --i) // Positionnement sur le champs
NEXT_FIELD(FD) ; // numéro FIELD de la ligne LINE.
STRING = MAKE_STRING_D() ;
SAFE_READ_1 ;
while (*CURRENT != '\t') // Récupération du contenu du
{ // champ dans une chaine
ADD_STRING_D(STRING, CURRENT[0]) ; // dynamique.
SAFE_READ_1 ;
}
CONTENT = STRING_D_to_STRING(STRING) ;
close(FD) ;
return CONTENT ;
} |