J'ai un petit problème avec mon code.
Je dois écrire dans un fichier un tableau de structure dans un premier temps,
puis relire ce fichier et afficher les données dans la console. Cependant, je
pédale dans la semoule, car les appels système ne sont pas mon fort (en réalité,
je n'ai pas vraiment tout compris).
Pour info, j'exécute ce programme sur une distribution UBUNTU.
Voici mon code, en espérant que vous pourrez corriger mes erreurs et me guider
dans la résolution de cet exercice.
1 #include <stdio.h>
2 #include <fcntl.h>
3
4 #define DIM 1000
5
6 struct complexe
7 {
8 char c;
9 int i;
10 float f;
11 };
12
13 int main()
14 {
15 struct complexe tableau[DIM];
16 int i, fichier;
17
18
19 for( i = 0 ; i < DIM ; i++ )
20 {
21 tableau[i].i = i;
22 tableau[i].c = (char)i;
23 tableau[i].f = (float)i;
24 }
25
26 fichier = open("test2", O_WRONLY|O_CREAT);
27
28 for( i = 0 ; i < DIM ; i++ )
29 write(fichier, tableau[i], sizeof(struct complexe));
30
31 close(fichier);
32
33 open("test2", O_RDONLY);
34
35 for( i = 0 ; i < DIM ; i++)
36 {
37 char *tampon;
38 read(fichier, tampon, sizeof(struct complexe));
39 printf("ligne %d : %s\n", i, tampon);
40 }
41 close(fichier);
42
43 }
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Mickaël Wolff
swoog wrote:
Pour info, j'exécute ce programme sur une distribution UBUNTU.
Quelle ligne de commande as-tu utilisé pour compiler ton source ? Quels sont les nombreux messages d'erreur et d'avertissement que le compilateur a crié ?
Voici mon code, en espérant que vous pourrez corriger mes erreurs et me guider dans la résolution de cet exercice.
[snip]
35 for( i = 0 ; i < DIM ; i++) 36 { 37 char *tampon; 38 read(fichier, tampon, sizeof(struct complexe));
Tu devais relire les manuels de read et write, tu as oublié quelques includes. De plus, tu ne teste aucun retour de fonctions, ce qui peut conduire à de droles de comportements.
Pour info, j'exécute ce programme sur une distribution UBUNTU.
Quelle ligne de commande as-tu utilisé pour compiler ton source ?
Quels sont les nombreux messages d'erreur et d'avertissement que le
compilateur a crié ?
Voici mon code, en espérant que vous pourrez corriger mes erreurs et me guider
dans la résolution de cet exercice.
[snip]
35 for( i = 0 ; i < DIM ; i++)
36 {
37 char *tampon;
38 read(fichier, tampon, sizeof(struct complexe));
Tu devais relire les manuels de read et write, tu as oublié quelques
includes. De plus, tu ne teste aucun retour de fonctions, ce qui peut
conduire à de droles de comportements.
Pour info, j'exécute ce programme sur une distribution UBUNTU.
Quelle ligne de commande as-tu utilisé pour compiler ton source ? Quels sont les nombreux messages d'erreur et d'avertissement que le compilateur a crié ?
Voici mon code, en espérant que vous pourrez corriger mes erreurs et me guider dans la résolution de cet exercice.
[snip]
35 for( i = 0 ; i < DIM ; i++) 36 { 37 char *tampon; 38 read(fichier, tampon, sizeof(struct complexe));
Tu devais relire les manuels de read et write, tu as oublié quelques includes. De plus, tu ne teste aucun retour de fonctions, ce qui peut conduire à de droles de comportements.
25 26 fichier = open("test2", O_WRONLY|O_CREAT); 27 28 for( i = 0 ; i < DIM ; i++ ) 29 write(fichier, tableau[i], sizeof(struct complexe));
Tu devrais passer l'adresse de la valeur à sauvegarder: write(fichier, &tableau[i], sizeof tableau[0]); (il serait bien de vérifier que tout s'est bien déroulé dans le write).
30 31 close(fichier); 32 33 open("test2", O_RDONLY); 34 35 for( i = 0 ; i < DIM ; i++) 36 { 37 char *tampon; 38 read(fichier, tampon, sizeof(struct complexe));
tampon pointe sur aucune zonne de mémoire allouée! Ce que tu as écrit va ecrire n'importe où en mémoire. Il faut là encore passer l'adresse de la zone mémoire qui va recevoir les données. Le mieux est d'allouer une seule valeur de struct complexe et de l'utiliser comme tampon d'entrée: { struct complexe tampon; read(fichier, (char*)&tampon, sizeof(tampon)); (note: idem il faudrait vérifier que l'on a bien lu sizeof(tampon)).
39 printf("ligne %d : %sn", i, tampon);
heu.. ici tu considère que tampon est une chaine, or c'est une struct... Ca n'a pas de sens. Tu veux peut-etre écrire: printf("ligne %d : c=%c i=%d ...n", i, tampon.c, tampon.i); Note: j'ai volontairement oublié d'imprimer le tampon.f... c'est pas le sujet ici.
40 } 41 close(fichier); 42 43 }
sam.
swoog a écrit :
25
26 fichier = open("test2", O_WRONLY|O_CREAT);
27
28 for( i = 0 ; i < DIM ; i++ )
29 write(fichier, tableau[i], sizeof(struct complexe));
Tu devrais passer l'adresse de la valeur à sauvegarder:
write(fichier, &tableau[i], sizeof tableau[0]);
(il serait bien de vérifier que tout s'est bien déroulé dans le write).
30
31 close(fichier);
32
33 open("test2", O_RDONLY);
34
35 for( i = 0 ; i < DIM ; i++)
36 {
37 char *tampon;
38 read(fichier, tampon, sizeof(struct complexe));
tampon pointe sur aucune zonne de mémoire allouée! Ce que tu as écrit va
ecrire n'importe où en mémoire. Il faut là encore passer l'adresse de la
zone mémoire qui va recevoir les données. Le mieux est d'allouer une
seule valeur de struct complexe et de l'utiliser comme tampon d'entrée:
{
struct complexe tampon;
read(fichier, (char*)&tampon, sizeof(tampon));
(note: idem il faudrait vérifier que l'on a bien lu sizeof(tampon)).
39 printf("ligne %d : %sn", i, tampon);
heu.. ici tu considère que tampon est une chaine, or c'est une struct...
Ca n'a pas de sens. Tu veux peut-etre écrire:
printf("ligne %d : c=%c i=%d ...n", i, tampon.c, tampon.i);
Note: j'ai volontairement oublié d'imprimer le tampon.f... c'est pas le
sujet ici.
25 26 fichier = open("test2", O_WRONLY|O_CREAT); 27 28 for( i = 0 ; i < DIM ; i++ ) 29 write(fichier, tableau[i], sizeof(struct complexe));
Tu devrais passer l'adresse de la valeur à sauvegarder: write(fichier, &tableau[i], sizeof tableau[0]); (il serait bien de vérifier que tout s'est bien déroulé dans le write).
30 31 close(fichier); 32 33 open("test2", O_RDONLY); 34 35 for( i = 0 ; i < DIM ; i++) 36 { 37 char *tampon; 38 read(fichier, tampon, sizeof(struct complexe));
tampon pointe sur aucune zonne de mémoire allouée! Ce que tu as écrit va ecrire n'importe où en mémoire. Il faut là encore passer l'adresse de la zone mémoire qui va recevoir les données. Le mieux est d'allouer une seule valeur de struct complexe et de l'utiliser comme tampon d'entrée: { struct complexe tampon; read(fichier, (char*)&tampon, sizeof(tampon)); (note: idem il faudrait vérifier que l'on a bien lu sizeof(tampon)).
39 printf("ligne %d : %sn", i, tampon);
heu.. ici tu considère que tampon est une chaine, or c'est une struct... Ca n'a pas de sens. Tu veux peut-etre écrire: printf("ligne %d : c=%c i=%d ...n", i, tampon.c, tampon.i); Note: j'ai volontairement oublié d'imprimer le tampon.f... c'est pas le sujet ici.
40 } 41 close(fichier); 42 43 }
sam.
Thierry B
On 2009-09-22, swoog wrote:
32 33 open("test2", O_RDONLY); 34
EPIC FAIL !
-- Collection de bugs: http://wwwzenger.informatik.tu-muenchen.de/persons/huckle/bugse.html
On 2009-09-22, swoog <nospam_dav.sea@free.fr> wrote:
32
33 open("test2", O_RDONLY);
34
EPIC FAIL !
--
Collection de bugs:
http://wwwzenger.informatik.tu-muenchen.de/persons/huckle/bugse.html
-------------- Build: Debug in hello ---------------
Compiling: main.c Linking console executable: binDebughello.exe C:devhellomain.c:1: error: syntax error before numeric constant C:devhellomain.c:1: error: syntax error at '#' token C:devhellomain.c:2: error: syntax error at '#' token C:devhellomain.c:4: error: syntax error at '#' token C:devhellomain.c:11: warning: ISO C does not allow extra `;' outside of a function Process terminated with status 1 (0 minutes, 1 seconds) 4 errors, 1 warnings
Retirons ces numéros de lignes ...
-------------- Build: Debug in hello ---------------
Compiling: main.c Linking console executable: binDebughello.exe C:devhellomain.c:14: warning: function declaration isn't a prototype C:devhellomain.c: In function `main': C:devhellomain.c:29: error: incompatible type for argument 2 of `write' Process terminated with status 1 (0 minutes, 0 seconds) 1 errors, 1 warnings
on y voit déjà plus clair...
Ceci-dit, il n'y a pas de fonction read() ni write() e langage C. Ce sont des fonctions du styème Unix (et des tout système compatible POSIX.1). Leur usage est rarement justifié, mais si tu y tiens, la doc est là :
tampon est un pointeur non initialisé. Tu passes donc une valeur indéterminée à une fonction. Le comportement est indéterminé
En supposant que l'écriture et la lecture se fasse sur la même machine, et dans les mêmes conditions (ce qui est le cas ci, mais c'est un cas très particulier et plutôt rare dans la pratique), tu peux utiliser le même type de structure à la lecture qu'à l'enregistrement. Il suffit donc de définir ceci :
read (fichier, &tampon, sizeof tampon);
Je recommande une séparation totale entre le code d'écriture et le code de lecture. Ca évite les erreurs de recyclage de variables ayant une valeur erronée
Enfin, pour valider un principe, il vaut mieux se limiter à une dizaine de valeurs que l'on peut vérifier visuellement rapidement...
#include <stdio.h> #include <fcntl.h>
#define DIM 10
struct complexe { char c; int i; float f; };
int main (void) { /* write */ { struct complexe tableau[DIM]; { int i; for (i = 0; i < DIM; i++) { tableau[i].i = i; tableau[i].c = (char) i; tableau[i].f = (float) i; } } { int fichier = open ("test2", O_WRONLY | O_CREAT); if (fichier != -1) { int i; for (i = 0; i < DIM; i++) write (fichier, tableau + i, sizeof *tableau);
close (fichier); } } }
/*read */ { int fichier = open ("test2", O_RDONLY); if (fichier != -1) { int i; for (i = 0; i < DIM; i++) { struct complexe tampon; read (fichier, &tampon, sizeof tampon); printf ("ligne %d : %d, '%c', %fn", i, tampon.i, tampon.c, tampon.f); } close (fichier); } } return 0; }
On 23 sep, 01:15, swoog <nospam_dav....@free.fr> wrote:
Voici mon code, en espérant que vous pourrez corriger mes erreurs et me guider
dans la résolution de cet exercice.
-------------- Build: Debug in hello ---------------
Compiling: main.c
Linking console executable: binDebughello.exe
C:devhellomain.c:1: error: syntax error before numeric constant
C:devhellomain.c:1: error: syntax error at '#' token
C:devhellomain.c:2: error: syntax error at '#' token
C:devhellomain.c:4: error: syntax error at '#' token
C:devhellomain.c:11: warning: ISO C does not allow extra `;'
outside of a function
Process terminated with status 1 (0 minutes, 1 seconds)
4 errors, 1 warnings
Retirons ces numéros de lignes ...
-------------- Build: Debug in hello ---------------
Compiling: main.c
Linking console executable: binDebughello.exe
C:devhellomain.c:14: warning: function declaration isn't a
prototype
C:devhellomain.c: In function `main':
C:devhellomain.c:29: error: incompatible type for argument 2 of
`write'
Process terminated with status 1 (0 minutes, 0 seconds)
1 errors, 1 warnings
on y voit déjà plus clair...
Ceci-dit, il n'y a pas de fonction read() ni write() e langage C. Ce
sont des fonctions du styème Unix (et des tout système compatible
POSIX.1). Leur usage est rarement justifié, mais si tu y tiens, la doc
est là :
tampon est un pointeur non initialisé. Tu passes donc une valeur
indéterminée à une fonction. Le comportement est indéterminé
En supposant que l'écriture et la lecture se fasse sur la même
machine, et dans les mêmes conditions (ce qui est le cas ci, mais
c'est un cas très particulier et plutôt rare dans la pratique), tu
peux utiliser le même type de structure à la lecture qu'à
l'enregistrement. Il suffit donc de définir ceci :
read (fichier, &tampon, sizeof tampon);
Je recommande une séparation totale entre le code d'écriture et le
code de lecture. Ca évite les erreurs de recyclage de variables ayant
une valeur erronée
Enfin, pour valider un principe, il vaut mieux se limiter à une
dizaine de valeurs que l'on peut vérifier visuellement rapidement...
#include <stdio.h>
#include <fcntl.h>
#define DIM 10
struct complexe
{
char c;
int i;
float f;
};
int main (void)
{
/* write */
{
struct complexe tableau[DIM];
{
int i;
for (i = 0; i < DIM; i++)
{
tableau[i].i = i;
tableau[i].c = (char) i;
tableau[i].f = (float) i;
}
}
{
int fichier = open ("test2", O_WRONLY | O_CREAT);
if (fichier != -1)
{
int i;
for (i = 0; i < DIM; i++)
write (fichier, tableau + i, sizeof *tableau);
close (fichier);
}
}
}
/*read */
{
int fichier = open ("test2", O_RDONLY);
if (fichier != -1)
{
int i;
for (i = 0; i < DIM; i++)
{
struct complexe tampon;
read (fichier, &tampon, sizeof tampon);
printf ("ligne %d : %d, '%c', %fn", i, tampon.i,
tampon.c,
tampon.f);
}
close (fichier);
}
}
return 0;
}
-------------- Build: Debug in hello ---------------
Compiling: main.c Linking console executable: binDebughello.exe C:devhellomain.c:1: error: syntax error before numeric constant C:devhellomain.c:1: error: syntax error at '#' token C:devhellomain.c:2: error: syntax error at '#' token C:devhellomain.c:4: error: syntax error at '#' token C:devhellomain.c:11: warning: ISO C does not allow extra `;' outside of a function Process terminated with status 1 (0 minutes, 1 seconds) 4 errors, 1 warnings
Retirons ces numéros de lignes ...
-------------- Build: Debug in hello ---------------
Compiling: main.c Linking console executable: binDebughello.exe C:devhellomain.c:14: warning: function declaration isn't a prototype C:devhellomain.c: In function `main': C:devhellomain.c:29: error: incompatible type for argument 2 of `write' Process terminated with status 1 (0 minutes, 0 seconds) 1 errors, 1 warnings
on y voit déjà plus clair...
Ceci-dit, il n'y a pas de fonction read() ni write() e langage C. Ce sont des fonctions du styème Unix (et des tout système compatible POSIX.1). Leur usage est rarement justifié, mais si tu y tiens, la doc est là :
tampon est un pointeur non initialisé. Tu passes donc une valeur indéterminée à une fonction. Le comportement est indéterminé
En supposant que l'écriture et la lecture se fasse sur la même machine, et dans les mêmes conditions (ce qui est le cas ci, mais c'est un cas très particulier et plutôt rare dans la pratique), tu peux utiliser le même type de structure à la lecture qu'à l'enregistrement. Il suffit donc de définir ceci :
read (fichier, &tampon, sizeof tampon);
Je recommande une séparation totale entre le code d'écriture et le code de lecture. Ca évite les erreurs de recyclage de variables ayant une valeur erronée
Enfin, pour valider un principe, il vaut mieux se limiter à une dizaine de valeurs que l'on peut vérifier visuellement rapidement...
#include <stdio.h> #include <fcntl.h>
#define DIM 10
struct complexe { char c; int i; float f; };
int main (void) { /* write */ { struct complexe tableau[DIM]; { int i; for (i = 0; i < DIM; i++) { tableau[i].i = i; tableau[i].c = (char) i; tableau[i].f = (float) i; } } { int fichier = open ("test2", O_WRONLY | O_CREAT); if (fichier != -1) { int i; for (i = 0; i < DIM; i++) write (fichier, tableau + i, sizeof *tableau);
close (fichier); } } }
/*read */ { int fichier = open ("test2", O_RDONLY); if (fichier != -1) { int i; for (i = 0; i < DIM; i++) { struct complexe tampon; read (fichier, &tampon, sizeof tampon); printf ("ligne %d : %d, '%c', %fn", i, tampon.i, tampon.c, tampon.f); } close (fichier); } } return 0; }
Je suis dans la continuité de la réponse de -ed- donc je ne reviens pas sur ce qui a été dit. Votre but était semble-t-il de copier puis relire l'image mémoire de votre tableau de structures. Cette solution a des avantgages et des inconvénients. Pour profiter de ces avantages, il faudrait alors sauver d'un bloc le tableau de structures, un seul write(). Puis le recharger d'un bloc, ou charger une structure particulière.
L'inconvénient c'est que cette méthode n'est pas adaptée aux échanges, ni même aux changements de version d'ailleurs. Le même programme compilé avec un changement dans la taille des int, char ou float, voire un padding ou un boutisme différent, et ça pourra ne pas fonctionner. Le choix est une question d'utilisation.
Une autre solution est donc de sérialiser vos données sous forme de texte. Lisible par l'homme est d'autres langages c'est mieux. Voici un premier jet, à partir de la version de -ed-, avec la contrainte de n'utiliser que open(), read() et write():
int main(void) { char s[60] = ""; puts("write 1"); { struct complexe tableau[DIM]; { int i; for (i = 0; i < DIM; i++) { tableau[i].i = i; tableau[i].c = '0' + (char) i; tableau[i].f = (float) i; } } { int fichier = open("test2", O_CREAT | O_WRONLY, 0644); if (fichier != -1) { int i; for (i = 0; i < DIM; i++) { sprintf(s, "%d %d %fn", tableau[i].i, tableau[i].c, tableau[i].f); write(fichier, s, strlen(s)); printf("%s", s); }
close(fichier); } } }
puts("read"); { int fichier = open("test2", O_RDONLY); if (fichier != -1) { int i, j; for (i = 0; i < DIM; i++) { struct complexe tampon; j = 0; do { read(fichier, &s[j], 1); } while (s[j++] != 'n'); sscanf(s, "%d %c %fn", &tampon.i, &tampon.c, &tampon.f); printf("ligne %d : %d, '%c', %fn", i, tampon.i, tampon.c, tampon.f); } close(fichier); } else { printf("%in", errno); } } return 0; }
-- Pierre Maurette
swoog, le 23/09/2009 a écrit :
Bonjour,
Bonjour,
Je suis dans la continuité de la réponse de -ed- donc je ne reviens pas
sur ce qui a été dit.
Votre but était semble-t-il de copier puis relire l'image mémoire de
votre tableau de structures. Cette solution a des avantgages et des
inconvénients. Pour profiter de ces avantages, il faudrait alors sauver
d'un bloc le tableau de structures, un seul write(). Puis le recharger
d'un bloc, ou charger une structure particulière.
L'inconvénient c'est que cette méthode n'est pas adaptée aux échanges,
ni même aux changements de version d'ailleurs. Le même programme
compilé avec un changement dans la taille des int, char ou float, voire
un padding ou un boutisme différent, et ça pourra ne pas fonctionner.
Le choix est une question d'utilisation.
Une autre solution est donc de sérialiser vos données sous forme de
texte. Lisible par l'homme est d'autres langages c'est mieux. Voici un
premier jet, à partir de la version de -ed-, avec la contrainte de
n'utiliser que open(), read() et write():
Je suis dans la continuité de la réponse de -ed- donc je ne reviens pas sur ce qui a été dit. Votre but était semble-t-il de copier puis relire l'image mémoire de votre tableau de structures. Cette solution a des avantgages et des inconvénients. Pour profiter de ces avantages, il faudrait alors sauver d'un bloc le tableau de structures, un seul write(). Puis le recharger d'un bloc, ou charger une structure particulière.
L'inconvénient c'est que cette méthode n'est pas adaptée aux échanges, ni même aux changements de version d'ailleurs. Le même programme compilé avec un changement dans la taille des int, char ou float, voire un padding ou un boutisme différent, et ça pourra ne pas fonctionner. Le choix est une question d'utilisation.
Une autre solution est donc de sérialiser vos données sous forme de texte. Lisible par l'homme est d'autres langages c'est mieux. Voici un premier jet, à partir de la version de -ed-, avec la contrainte de n'utiliser que open(), read() et write():
int main(void) { char s[60] = ""; puts("write 1"); { struct complexe tableau[DIM]; { int i; for (i = 0; i < DIM; i++) { tableau[i].i = i; tableau[i].c = '0' + (char) i; tableau[i].f = (float) i; } } { int fichier = open("test2", O_CREAT | O_WRONLY, 0644); if (fichier != -1) { int i; for (i = 0; i < DIM; i++) { sprintf(s, "%d %d %fn", tableau[i].i, tableau[i].c, tableau[i].f); write(fichier, s, strlen(s)); printf("%s", s); }
close(fichier); } } }
puts("read"); { int fichier = open("test2", O_RDONLY); if (fichier != -1) { int i, j; for (i = 0; i < DIM; i++) { struct complexe tampon; j = 0; do { read(fichier, &s[j], 1); } while (s[j++] != 'n'); sscanf(s, "%d %c %fn", &tampon.i, &tampon.c, &tampon.f); printf("ligne %d : %d, '%c', %fn", i, tampon.i, tampon.c, tampon.f); } close(fichier); } else { printf("%in", errno); } } return 0; }
-- Pierre Maurette
Pierre Maurette
(supersedes )
swoog, le 23/09/2009 a écrit :
Bonjour,
Bonjour,
Je suis dans la continuité de la réponse de -ed- donc je ne reviens pas sur ce qui a été dit. Votre but était semble-t-il de copier puis relire l'image mémoire de votre tableau de structures. Cette solution a des avantgages et des inconvénients. Pour profiter de ces avantages, il faudrait alors sauver d'un bloc le tableau de structures, un seul write(). Puis le recharger d'un bloc, ou charger une structure particulière.
L'inconvénient c'est que cette méthode n'est pas adaptée aux échanges, ni même aux changements de version d'ailleurs. Le même programme compilé avec un changement dans la taille des int, char ou float, voire un padding ou un boutisme différent, et ça pourra ne pas fonctionner. Le choix est une question d'utilisation.
Une autre solution est donc de sérialiser vos données sous forme de texte. Lisible par l'homme est d'autres langages c'est mieux. Voici un premier jet, à partir de la version de -ed-, avec la contrainte de n'utiliser que open(), read() et write():
[Je corrige une erreur en centralisant la définition de la chaîne de format. Il faut décider si le char de la structure est un caractère ou un entier. Si c'était un entier, il faudrait préciser son signe, signed char ou unsigned char. C'est donc un caractère, et il peut y avoir des problèmes avec certaines valeurs non imprimables. J'avais d'ailleurs initialisé à '0' + i.]
Je suis dans la continuité de la réponse de -ed- donc je ne reviens pas
sur ce qui a été dit.
Votre but était semble-t-il de copier puis relire l'image mémoire de
votre tableau de structures. Cette solution a des avantgages et des
inconvénients. Pour profiter de ces avantages, il faudrait alors sauver
d'un bloc le tableau de structures, un seul write(). Puis le recharger
d'un bloc, ou charger une structure particulière.
L'inconvénient c'est que cette méthode n'est pas adaptée aux échanges,
ni même aux changements de version d'ailleurs. Le même programme
compilé avec un changement dans la taille des int, char ou float, voire
un padding ou un boutisme différent, et ça pourra ne pas fonctionner.
Le choix est une question d'utilisation.
Une autre solution est donc de sérialiser vos données sous forme de
texte. Lisible par l'homme est d'autres langages c'est mieux. Voici un
premier jet, à partir de la version de -ed-, avec la contrainte de
n'utiliser que open(), read() et write():
[Je corrige une erreur en centralisant la définition de la chaîne de
format. Il faut décider si le char de la structure est un caractère ou
un entier. Si c'était un entier, il faudrait préciser son signe, signed
char ou unsigned char. C'est donc un caractère, et il peut y avoir des
problèmes avec certaines valeurs non imprimables. J'avais d'ailleurs
initialisé à '0' + i.]
Je suis dans la continuité de la réponse de -ed- donc je ne reviens pas sur ce qui a été dit. Votre but était semble-t-il de copier puis relire l'image mémoire de votre tableau de structures. Cette solution a des avantgages et des inconvénients. Pour profiter de ces avantages, il faudrait alors sauver d'un bloc le tableau de structures, un seul write(). Puis le recharger d'un bloc, ou charger une structure particulière.
L'inconvénient c'est que cette méthode n'est pas adaptée aux échanges, ni même aux changements de version d'ailleurs. Le même programme compilé avec un changement dans la taille des int, char ou float, voire un padding ou un boutisme différent, et ça pourra ne pas fonctionner. Le choix est une question d'utilisation.
Une autre solution est donc de sérialiser vos données sous forme de texte. Lisible par l'homme est d'autres langages c'est mieux. Voici un premier jet, à partir de la version de -ed-, avec la contrainte de n'utiliser que open(), read() et write():
[Je corrige une erreur en centralisant la définition de la chaîne de format. Il faut décider si le char de la structure est un caractère ou un entier. Si c'était un entier, il faudrait préciser son signe, signed char ou unsigned char. C'est donc un caractère, et il peut y avoir des problèmes avec certaines valeurs non imprimables. J'avais d'ailleurs initialisé à '0' + i.]
1/ je ne suis pas sur que lui faire completement son exercice soit une bonne idee.
2/ comme d'autres l'ont deja mentionne, un peu plus d'attention a ce qu'on fait devrait eviter la majorite des problemes. On a ici un code que je qualifierais de "code Shadock": je fais n'importe quoi sans comprendre en esperant que ca finira par marcher. La principale chose qui va aider, c'est plus de rigueur: demander des avertissements au compilo, prendre ces avertissements en compte, et relire attentivement ce qu'on ecrit.
3/ de facon generale, il faudra a un moment ou un autre comprendre comment marche la memoire...
l'image mentale que je me fais de read et write, c'est un truc qui copie des donnees entre une zone memoire et le disque. Il faut que la zone memoire soit bien definie (en particulier allouee). D'ou necessite d'avoir un vrai tampon, et pas juste un pointeur qui ne pointe sur rien.
Genre:
char t[256];
n1 = read(rfd, t, 256); va lire n <= 256 octets dans le tampon.
et n2 = write(wfd, t, 256); va essayer d'ecrire 256 octets depuis le tampon (et va dire combien il a ecrit).
Le truc le plus vicieux avec les entrees-sorties unix, c'est qu'on ne peut pas presumer des valeurs de retour de read et write: sans de grosses hypotheses supplementaires, on peut tres bien avoir n1 < 256 ou n2 < 256.
Il faut "coder defensif", en consequence...
1/ je ne suis pas sur que lui faire completement son exercice soit une
bonne idee.
2/ comme d'autres l'ont deja mentionne, un peu plus d'attention a ce qu'on
fait devrait eviter la majorite des problemes. On a ici un code que je
qualifierais de "code Shadock": je fais n'importe quoi sans comprendre en
esperant que ca finira par marcher. La principale chose qui va aider, c'est
plus de rigueur: demander des avertissements au compilo, prendre ces
avertissements en compte, et relire attentivement ce qu'on ecrit.
3/ de facon generale, il faudra a un moment ou un autre comprendre comment
marche la memoire...
l'image mentale que je me fais de read et write, c'est un truc qui copie
des donnees entre une zone memoire et le disque. Il faut que la zone
memoire soit bien definie (en particulier allouee). D'ou necessite d'avoir
un vrai tampon, et pas juste un pointeur qui ne pointe sur rien.
Genre:
char t[256];
n1 = read(rfd, t, 256); va lire n <= 256 octets dans le tampon.
et
n2 = write(wfd, t, 256); va essayer d'ecrire 256 octets depuis le tampon
(et va dire combien il a ecrit).
Le truc le plus vicieux avec les entrees-sorties unix, c'est qu'on ne
peut pas presumer des valeurs de retour de read et write: sans de grosses
hypotheses supplementaires, on peut tres bien avoir n1 < 256 ou n2 < 256.
1/ je ne suis pas sur que lui faire completement son exercice soit une bonne idee.
2/ comme d'autres l'ont deja mentionne, un peu plus d'attention a ce qu'on fait devrait eviter la majorite des problemes. On a ici un code que je qualifierais de "code Shadock": je fais n'importe quoi sans comprendre en esperant que ca finira par marcher. La principale chose qui va aider, c'est plus de rigueur: demander des avertissements au compilo, prendre ces avertissements en compte, et relire attentivement ce qu'on ecrit.
3/ de facon generale, il faudra a un moment ou un autre comprendre comment marche la memoire...
l'image mentale que je me fais de read et write, c'est un truc qui copie des donnees entre une zone memoire et le disque. Il faut que la zone memoire soit bien definie (en particulier allouee). D'ou necessite d'avoir un vrai tampon, et pas juste un pointeur qui ne pointe sur rien.
Genre:
char t[256];
n1 = read(rfd, t, 256); va lire n <= 256 octets dans le tampon.
et n2 = write(wfd, t, 256); va essayer d'ecrire 256 octets depuis le tampon (et va dire combien il a ecrit).
Le truc le plus vicieux avec les entrees-sorties unix, c'est qu'on ne peut pas presumer des valeurs de retour de read et write: sans de grosses hypotheses supplementaires, on peut tres bien avoir n1 < 256 ou n2 < 256.