Problème: se déplacer dans un fichier

Problème: se déplacer dans un fichier - C - Programmation

Marsh Posté le 29-01-2007 à 15:22:24    

Bonjour à tous et à toutes !
 
Pour demain j'ai a rendre un tp sur une nouvelle notion que l'on a pas acquérie encore qui est les fichiers.
 
Le tp consiste à allez lire des informations dans un fichier .txt pour pouvoir établir une facture pour un client. Le client rentre le code de l'article et le programme va chercher dans le .txt le nom et le prix de l'article en fonction de ce code.
 
Mon problème est que je n'arrive pas du tout à me déplacer dans le fichier je sais pas comment on fait et on a aucun cours !
 
Donc une petite aide serait fort sympathique ^^
 
merci!

Reply

Marsh Posté le 29-01-2007 à 15:22:24   

Reply

Marsh Posté le 29-01-2007 à 15:41:29    

En C, on peut utiliser les fonctions suivantes :
 
fopen(...) N.B Attention, préciser si le fichier est binaire ou si c'est du texte (il n'y a pas de gestion des fichiers indexés).
fclose()
 
Entre les fopen et fclose, faire une boucle until feof() ou jusqu'à avoir trouvé l'info désirée.
 
Dans la boucle, appeler fgets() pour lire une ligne de texte à la fois (fread() sert généralement pour les fichiers binaires), ou fgetc() pour lire seulement un caractère à la fois.
Après fgets ou fgetc, un pointeur, que l'on ne voit pas, est automatiquement incrémenté.
 
Pour se déplacer on peut utiliser fseek() (habituellement dans un fichier binaire, rarement dans un fichier texte, parce que ceux-ci ont souvent des longueurs de lignes variables et donc on peut rarement déterminer à priori que la n-ième ligne commence à la poisition x). La fonction ftell() permet de connaitre la position courante.

Message cité 1 fois
Message édité par olivthill le 29-01-2007 à 15:43:02
Reply

Marsh Posté le 29-01-2007 à 15:43:35    

Qhrim a écrit :

Bonjour à tous et à toutes !
 
Pour demain j'ai a rendre un tp sur une nouvelle notion que l'on a pas acquérie encore qui est les fichiers.
 
Le tp consiste à allez lire des informations dans un fichier .txt pour pouvoir établir une facture pour un client. Le client rentre le code de l'article et le programme va chercher dans le .txt le nom et le prix de l'article en fonction de ce code.
 
Mon problème est que je n'arrive pas du tout à me déplacer dans le fichier je sais pas comment on fait et on a aucun cours !
 
Donc une petite aide serait fort sympathique ^^
 
merci!


 
Je présume que tu utilises des "FILE*"
Bon, pour te déplacer tu as 2 façons de faire

  • lire un caractère (ou une suite de caractère) => la fonction de lecture (style "fgetc()" par exemple) te renvoie (ou te rempli une zone avec) les caractères lus et déplace le pointeur interne du fichier du nombre de caractères lus => lors de la lecture suivante, tu lis à partir de l'endroit où tu t'es arrêté
  • utiliser la fonction "fseek()" => elle te déplace le pointeur interne du nombre de caractères demandés => fais un "man" et tu verras comment on l'utilise


Message édité par Sve@r le 29-01-2007 à 15:44:29

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 29-01-2007 à 15:50:23    

olivthill a écrit :

Entre les fopen et fclose, faire une boucle until feof() ou jusqu'à avoir trouvé l'info désirée.


NON !!!!!  :non:  
Déjà la boucle "until" n'existe pas en C  :pfff:  
Ensuite la fonction "feof()" ne détecte pas la fin de fichier (faudrait quand-même lire le man de temps en temps)
Son but est, une fois que la lecture du fichier s'est terminée, d'indiquer si on a fini de lire parce qu'on est en fin de fichier ou si on a fini de lire pour une autre raison (fichier perdu, disque dur crashé, etc...)
 
La bonne façon de traiter un fichier est de faire une boucle

while (<fonction_de_lecture>(...) != <valeur_spéciale_quand_il_n'y_a_plus_rien_à_lire> )
{
     <traitement des octets lus>
}


Pour connaître la valeur spéciale, faut faire un "man" de la fonction de lecture utilisée. Par exemple "fgetc()" renvoie "EOF"; "fread()" renvoie "0"; "fgets()" renvoie "NULL" etc...


Message édité par Sve@r le 29-01-2007 à 15:52:24

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 29-01-2007 à 15:52:14    

Merci a vous deux pour vos réponses ca va déja mieux.
 
J'utilise un fichier texte, est-ce qu'il existe une fonction permettant d'aller directement a la ligne désiré?
 
Mon fichier texte je l'ai organiser comme ceci:
 
1 grille-pain 270,90
2 micro-onde 399,50
etc...
 
en faite je met "code article prix". Donc mon but va être de retrouver le bon code saisie par l'utilisateur et d'extraire le nom de l'article et le prix mais j'ai vraiment du mal...

Reply

Marsh Posté le 29-01-2007 à 15:57:07    

Qhrim a écrit :

Merci a vous deux pour vos réponses ca va déja mieux.
 
J'utilise un fichier texte, est-ce qu'il existe une fonction permettant d'aller directement a la ligne désiré?
 
Mon fichier texte je l'ai organiser comme ceci:
 
1 grille-pain 270,90
2 micro-onde 399,50
etc...


En fait, ton éditeur te montre ton fichier ligne par ligne mais dans la réalité, il est écrit "physiquement" comme ceci:
1 grille-pain 270,90<return>2 micro-onde 399,50<return>etc...
C'est l'éditeur qui repère les "<return>" et qui affiche proprement les lignes
 
T'as la fonction "fgets()" qui te permet de lire une ligne entière (elle s'arrête à chaque "return" ).
Personnellement, je ferais comme ceci
lire une ligne avec "fgets()" => la fonction te stocke ta ligne dans une zone de travail
faire un "sscanf()" avec cette zone pour en extraire

  • le code
  • l'article
  • le prix

comparer le code récupéré avec le code que tu cherches et si c'est correct afficher l'ensemble
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 29-01-2007 à 16:05:01    

Trés bonne démarche je vais essayer merci beaucoup !!!
 
On ne peut pas faire une fonction qui detecte les <return> aussi? comme ça si l'utilisateur rentre le code "5" on detecte 5 return avant de faire fgets et sscanf non?

Reply

Marsh Posté le 29-01-2007 à 16:23:58    

Qhrim a écrit :

Trés bonne démarche


Oui ben je suis un peu habitué.... ;)  
 

Qhrim a écrit :

On ne peut pas faire une fonction qui detecte les <return> aussi?


ben le pb c'est que pour détecter un "<return>" faut d'abord le lire => ensuite tu peux plus le relire puisque t'as dépassé la zone => retour en arrière avec "fseek()" => devient trop compliqué non ???


Message édité par Sve@r le 29-01-2007 à 16:25:12

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 29-01-2007 à 16:29:11    

Oui je vais garder ta méthode c'est vrai que ca a l'air plus simple :)
 
Mais j'ai une question, quand on fait fgets(), je le stock ou? dans une chaîne de caractères?
 
Et je n'ai pas trés bien compris a quoi sert sscanf()...

Message cité 1 fois
Message édité par Qhrim le 29-01-2007 à 18:15:11
Reply

Marsh Posté le 29-01-2007 à 18:11:47    

Qhrim a écrit :

Mais j'ai une question, quand on fait fgets(), je le stock ou? dans une chaîne de caractères?


Ben oui (man fgets) => le premier paramètre est l'adresse de la zone où stocker => faut bien entendu que de ton coté tu aies une zone assez grande pour stocker une ligne dont tu ne connais pas la taille à l'avance => tu peux donc "estimer" qu'aucune ligne ne dépassera 512 octets (ou 1024 ou 2048) et tu définis une zone de cette taille.
 
Si vraiment tu veux traiter un jour un fichier dont tu ne peux absolument pas estimer la taille max d'une ligne, alors tu peux utiliser la fonction "getline()" qui s'adapte à toute longueur de ligne => c'est la fonction qui alloue elle-même l'espace nécessaire pour stocker la ligne lue => à toi de libérer l'espace (free()) quand tu n'en as plus besoin...
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 29-01-2007 à 18:11:47   

Reply

Marsh Posté le 29-01-2007 à 18:20:10    

Donc la fonction fgets() contient 3 paramètres:
 
- la chaîne de caractère dans laquelle je vais mettre la ligne,
- Le nombre de caracères lu, c'est la le problème je met quoi? car je ne connait pas la longueur de la ligne,
- Le fichier a lire,
 
C'est bien ca?

Reply

Marsh Posté le 29-01-2007 à 18:40:59    

Qhrim a écrit :

Donc la fonction fgets() contient 3 paramètres:
 
- la chaîne de caractère dans laquelle je vais mettre la ligne,
- Le nombre de caracères lu, c'est la le problème je met quoi? car je ne connait pas la longueur de la ligne,
- Le fichier a lire,
 
C'est bien ca?


Presque. le 2° paramètre indique la longueur de ta zone de stockage. Si la ligne est plus courte c'est pas grave, mais si elle est plus longue elle sera tronquée pour ne pas dépasser la zone de stockage. A toi d'estimer quelle peut être la longueur max d'une ligne pour tailler ta zone en conséquence. Par exemple, si ton article fait 20 caractère max (parce que ce fichier a été écrit par un autre programme où c'est défini comme ça), alors ta ligne ne fera que

  • taille indice (pas plus de 3 ou 4 au pire)
  • espace
  • 20
  • espace
  • prix (3 chiffres ou 4 plus virgule plus 2 donc 6 ou 7)
  • return

Donc au total 34. Si tu tailles ta zone à 128 ou 256 tu ne demandes pas trop de mémoire et tu as de grandes chances de ne jamais avoir de ligne qui dépasse. Ensuite tout dépend de la criticité de ton programme. Si tu dois faire un programme pour une centrale nucléaire, vaut mieux éviter de faire trop d'estimations et essayer de controler au maximum tes inconnues. Si tu travailles pour un TP de cours, ça peut aller...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 29-01-2007 à 18:46:45    

Oui je vais mettre 128 je serais tranquille :D mais j'espère que la prof ne va pas aller s'amuser a modifier la longueur de la ligne :)
 
Merci en tout cas Sve@r j'ai apprit plein de chose grace a toi ;)

Reply

Marsh Posté le 29-01-2007 à 19:29:04    

Qhrim a écrit :

Merci en tout cas Sve@r j'ai appris plein de chose grace a toi ;)


C'est parce que j'ai été le premier à répondre. Mais quand ce sera Harkonnen ou Elmoricq ou Taz ou Joel F ou Delahaye qui te répondront, là tu connaitras la vraie signification du verbe "apprendre"... (quoique Taz soit plus un fan de la cat. C++ que de la cat. C...)

Message cité 1 fois
Message édité par Sve@r le 30-01-2007 à 07:09:39

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 30-01-2007 à 10:49:58    

Le plus simple pour la structure du fichier est de séparer les champs de l'article par un \; ou un caractère dont tu es sûr qu'il n'apparaitra pas dans la composition des champs, c'est plus sur qu'un espace. Renseigne toi sur le format CSV.
C'est plus facile à lire, un fgets suivi d'un strtok pour la recherche des champs

Reply

Marsh Posté le 30-01-2007 à 11:38:17    

Trap D a écrit :

Le plus simple pour la structure du fichier est de séparer les champs de l'article par un \; ou un caractère dont tu es sûr qu'il n'apparaitra pas dans la composition des champs, c'est plus sur qu'un espace. Renseigne toi sur le format CSV.


Il n'est pas maître de sa structure, c'est un fichier qu'il reçoit de l'extérieur...
 

Trap D a écrit :

C'est plus facile à lire, un fgets suivi d'un strtok pour la recherche des champs


Non :non:  
Quand on a une entrée formatée de type "géométrie fixe", sscanf() est fait pour ça. C'est quand-même mieux de mettre un seul sscanf qu'une boucle while() strtok()
De plus, strtok est hyper dangereuse du fait qu'elle utilise un pointeur statique pour mémoriser les appels successifs. Donc si tu imbriques deux strtok dans deux boucles différentes, il y aura mélange.
 
Maintenant, si tu as une entrée de type "géométrie variable", alors on peut se pencher sur la solution de la boucle strtok(). Mais alors il vaut mieux lui préférer "strtok_r()" où c'est toi qui gère la mémorisation du pointeur courant....


Message édité par Sve@r le 30-01-2007 à 11:40:27

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 30-01-2007 à 13:28:10    

Effectivement il n'est pas maître de la structure du fichier, mais perso je n'aime pas le sscanf et je préfère manipuler les chaines moi-même avec strtok (ou sa version safe strtok_r).

Reply

Marsh Posté le 30-01-2007 à 19:15:13    

Trap D a écrit :

...perso je n'aime pas le sscanf et je préfère manipuler les chaines moi-même avec strtok (ou sa version safe strtok_r).


Ben c'est comme si tu me disais "je n'aime pas strcpy() et je préfère copier les chaînes avec memcpy()". Même si c'est possible, c'est plus "bizarre".
J'utilise souvent sscanf qui est totalement fiable si l'entrée qu'on lui fournit est bien formatée...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 30-01-2007 à 23:19:50    

Bonsoir,
 
Voila j'ai quasi terminer mon programme ^^ a la fin je dois afficher la facture complète, article, quantité etc...
 
j'ai donc tout stocker dans une structure.
 
Le problème est que quand j'affiche le nom de l'article, il m'affiche <null> à la place et je n'arrive pas a voir d'ou ca vient :s

Reply

Marsh Posté le 31-01-2007 à 00:29:36    

Qhrim a écrit :

Mon problème est que je n'arrive pas du tout à me déplacer dans le fichier je sais pas comment on fait et on a aucun cours !


Tu n'as pas de livre de C ? Il y a des références de cours et de livre en ligne sur mon site.
 

  • fopen()
  • fgets() (lecture d'une ligne)
  • fclose()


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 00:33:52    

Qhrim a écrit :

Trés bonne démarche je vais essayer merci beaucoup !!!
 
On ne peut pas faire une fonction qui detecte les <return> aussi? comme ça si l'utilisateur rentre le code "5" on detecte 5 return avant de faire fgets et sscanf non?


fgets() fait une lecture par ligne (si le tableau est suffisamment grand...). Il suffit de les compter. Mais il est rare que les codes articles soient consécutifs, ni même triés. Il vaut mieux être indépendant et tester chaque ligne. C'est pas long...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 00:34:59    

Emmanuel Delahaye a écrit :

Tu n'as pas de livre de C ? Il y a des références de cours et de livre en ligne sur mon site.
 

  • fopen()
  • fgets() (lecture d'une ligne)
  • fclose()


En faite j'ai enfin réussi a piger la lecture de fichier (je n'en suis pas encore a l'écriture), mais la j'ai un tout autre problème bien différent!!
 
En effet, si j'effectue un printf de la chaîne de caractère qui contient mon article comme ceci:
 
printf("L'article choisi est %s",fact[i].art);
 
il m'affiche <null> a la place de l'article :/

Reply

Marsh Posté le 31-01-2007 à 00:35:46    

Emmanuel Delahaye a écrit :

fgets() fait une lecture par ligne (si le tableau est suffisamment grand...). Il suffit de les compter. Mais il est rare que les codes articles soient consécutifs, ni même triés. Il vaut mieux être indépendant et tester chaque ligne. C'est pas long...


 
C'est ce que j'ai fait a l'aide d'un while qui detecte le bon code et ca marche bien maintenant :)

Reply

Marsh Posté le 31-01-2007 à 00:35:58    

Qhrim a écrit :

Donc la fonction fgets() contient 3 paramètres:
 
- la chaîne de caractère dans laquelle je vais mettre la ligne,
- Le nombre de caracères lu, c'est la le problème je met quoi? car je ne connait pas la longueur de la ligne,


WTF ? La taille du tableau de char concerné par le premier paramètre. C'est écrit dans la doc, non ? Faut pas inventer. Faut lire...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 00:37:36    

Sve@r a écrit :

C'est parce que j'ai été le premier à répondre. Mais quand ce sera Harkonnen ou Elmoricq ou Taz ou Joel F ou Delahaye qui te répondront, là tu connaitras la vraie signification du verbe "apprendre"... (quoique Taz soit plus un fan de la cat. C++ que de la cat. C...)


Ne fais pas le modeste. Tu expliques très bien des choses justes.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 00:39:36    

Qhrim a écrit :

Voila j'ai quasi terminer mon programme ^^ a la fin je dois afficher la facture complète, article, quantité etc...
 
j'ai donc tout stocker dans une structure.
 
Le problème est que quand j'affiche le nom de l'article, il m'affiche <null> à la place et je n'arrive pas a voir d'ou ca vient :s


Ca veut dire que tu as passé une valeur valant NULL à printf(). C'est mal. Montre ton code.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 00:42:00    

Code :
  1. #include<stdio.h>
  2. #include<conio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. #define ref "c:\\ref.txt"
  6. void main(void)
  7. {
  8. clrscr();
  9. FILE *f1;
  10. char codeuti[3],codefi[3],*line,*prix;
  11. int nbart=0,i=0,j=0,cd=0,a=0,m=0,n=0;
  12. float tot=0;
  13. new char[128];
  14. /* Ouverture du fichier */
  15. f1=fopen(ref,"r" );
  16. if(f1==NULL)
  17. {
  18.  printf("Impossible d'ouvrir le fichier!\n" );
  19.  getch();
  20.  exit(1);
  21. }
  22. /**/
  23. fflush(stdin);
  24. printf("\t\tBienvenue dans ce programme de création de facture!" );
  25. printf("\n\nCombien d'article(s) voulez-vous facturer? " );
  26. scanf("%i",&nbart);
  27. while((nbart<=0)||(nbart>20))
  28. {
  29.  printf("\nVous ne pouvez pas rentrer 0 articles, ni en entrez plus qu'il n'y en a de différents..." );
  30.  printf("\nVeuillez saisir à nouveau le nombre d'article(s) désirez: " );
  31.  scanf("%i",&nbart);
  32. }
  33. struct facture
  34. {
  35.  char *art;
  36.  int qt;
  37.  float punit;
  38.  float mont;
  39. }fact[20];
  40. for(i=0;i<nbart;i++)
  41. {
  42.  a=0;
  43.  m=0;
  44.  n=0;
  45.  printf("\nCode article? " );
  46.  fflush(stdin);
  47.  gets(codeuti);
  48.  cd=atoi(codeuti);
  49.  while((cd<=0)||(cd>20))
  50.  {
  51.   printf("\n* * article inexistant * * Redonnez le code: " );
  52.   gets(codeuti);
  53.   cd=atoi(codeuti);
  54.  }
  55.  if(cd<10)
  56.   codeuti[1]=0;
  57.  rewind(f1);
  58.  while(a!=1)
  59.  {
  60.   j=0;
  61.   fflush(stdin);
  62.   fgets(line,128,f1);
  63.   while(line[j]!=47)
  64.   {
  65.    codefi[j]=line[j];
  66.    codefi[j+1]=0;
  67.    j++;
  68.   }
  69.   j+=1;
  70.   if(strcmp(codefi,codeuti)==0)
  71.    a=1;
  72.  }
  73.  while(line[j]!=47)
  74.  {
  75.   fact[i].art[m]=line[j];
  76.   fact[i].art[m+1]=0;
  77.   j++;
  78.   m++;
  79.  }
  80.  j++;
  81.  while(line[j]!=47)
  82.  {
  83.   prix[n]=line[j];
  84.   prix[n+1]=0;
  85.   j++;
  86.   n++;
  87.  }
  88.  fflush(stdin);
  89.  printf("\nQuantité de %s au prix unitaire de %s euros? ",fact[i].art,prix);
  90.  scanf("%i",&fact[i].qt);
  91.  fact[i].punit=atof(prix);
  92.  fact[i].mont=fact[i].punit*fact[i].qt;
  93.  tot+=fact[i].mont;
  94. }
  95. /* Fermeture du fichier */
  96. fclose(f1);
  97. /**/
  98. /* Affichage facture */
  99. clrscr();
  100. printf("\t\t\t\t\tFACTURE\n\n" );
  101. printf("\tARTICLE\t\t\tNBRE\t\tP-UNIT\t\tMONTANT" );
  102. for(i=0;i<nbart;i++)
  103. {
  104.  printf("\n\n\t%s\t\t%i\t\t%.2f\t\t%.2f",fact[i].art,fact[i].qt,fact[i].punit,fact[i].mont);
  105. }
  106. printf("\n\n\t\t\tTOTAL:\t\t\t\t\t%.2f",tot);
  107. /**/
  108. getch();
  109. clrscr();
  110. exit(1);
  111. }


Message édité par Qhrim le 31-01-2007 à 00:44:18
Reply

Marsh Posté le 31-01-2007 à 00:45:11    

Emmanuel Delahaye a écrit :

WTF ? La taille du tableau de char concerné par le premier paramètre. C'est écrit dans la doc, non ? Faut pas inventer. Faut lire...


 
j'utilise des pointeurs je définie pas la taille .

Reply

Marsh Posté le 31-01-2007 à 00:50:00    

Qhrim a écrit :

j'utilise des pointeurs je définie pas la taille .


La taille ne va pas se définir toute seule comme par magie.
Il faut passer l'adresse d'un bloc ayant une taille déterminée. Soit tu utilises un tableau


   char line[128];

 

  fgets(line, sizeof line, fp);


soit tu utilises un pointeur initialisé avec l'adresse d'un bloc valide :

Code :
  1. size_t n = 128;
  2.    char *line = malloc (n);
  3.    if (line != NULL)
  4.    {
  5.       fgets(line, n, fp);


qu'il faut bien sûr penser à libérer...


Message édité par Emmanuel Delahaye le 31-01-2007 à 00:51:23

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 00:54:19    

Ah et bien la prof nous avait pourtant clairement expliquer qu'un pointeur s'adaptait a la taille demander...
 
Enfin merci c'est déja plus clair maintenant !
 
reste toujours ce problème de <null>...

Reply

Marsh Posté le 31-01-2007 à 00:58:13    

Qhrim a écrit :

Ah et bien la prof nous avait pourtant clairement expliquer qu'un pointeur s'adaptait a la taille demander..


Change de prof, et vite. Je donne des cours de C, des vrais, ça t'intéresse ?

 

Message cité 2 fois
Message édité par Emmanuel Delahaye le 31-01-2007 à 00:58:27

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 01:05:29    

Emmanuel Delahaye a écrit :

Change de prof, et vite. Je donne des cours de C, des vrais, ça t'intéresse ?


 
Elle nous a aussi dit qu'il fallait allouer un espace mémoire du genre:
 
new char[128];
 
pas trop compris ^^
 

Reply

Marsh Posté le 31-01-2007 à 09:48:23    

Qhrim a écrit :

Elle nous a aussi dit qu'il fallait allouer un espace mémoire du genre:
 
new char[128];


Ca c'est du C++. Rien à voir avec le C. Mais c'est quoi cette école ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 17:17:31    

Emmanuel Delahaye a écrit :

Ca veut dire que tu as passé une valeur valant NULL à printf(). C'est mal. Montre ton code.


Mais non c'est pas "mal". printf sait gérer ce genre de cas donc ça va (encore) :D  
 

Emmanuel Delahaye a écrit :

Ne fais pas le modeste. Tu expliques très bien des choses justes.


:jap:  
 

Qhrim a écrit :

Ah et bien la prof nous avait pourtant clairement expliquer qu'un pointeur s'adaptait a la taille demander...


Un pointeur ne s'adapte jamais à quoi que ce soit. Ce n'est qu'une variable qui contient un simple nombre, rien de plus. Sauf que ce nombre est en fait une adresse mémoire (donc un n° de case mémoire) et à cette adresse, il y a une valeur (forcément puisque toute case mémoire contient une valeur) que tu peux récupérer grace à l'opérateur "étoile".
Va récupérer mon cours de  ici http://fr.lang.free.fr/cours/Langa [...] e_v2.0.pdf il y a un gros chapitre très détaillé sur les pointeurs...
 

Qhrim a écrit :

Elle nous a aussi dit qu'il fallait allouer un espace mémoire du genre:  
 
new char[128];
 
pas trop compris
 


"allouer" signifie "réserver". Dans cet exemple, tu réserves de façon dynamique 128 octets qui seront attribués à la variable (dont le nom n'est pas affiché ici). Ca sert à demander au système de te donner des cases mémoires en dynamique (si par exemple le nombre de cases nécessaires est issu d'un calcul, tu ne peux pas utiliser de tableaux car tu ne sais pas, au moment où tu écrits ton code, de combien t'auras besoin => nécessaire alors de passer par une allocation).
Mais comme l'a dit Emmanuel, l'instruction "new" est une instruction C++ et son "équivalent" C est la fonction "malloc()" (Memory ALLOCate)

Message cité 1 fois
Message édité par Sve@r le 31-01-2007 à 18:47:13

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 31-01-2007 à 19:11:31    

Sve@r a écrit :

Mais non c'est pas "mal". printf sait gérer ce genre de cas donc ça va (encore)


Non. A ma connaissance (je vais quand même vérifier), ça ne va pas du tout. Le fait que NULL soit géré avec "%s" est un effet direct de la QoI (Quality of Implementation). Pas du tout du langage C pour lequel c'est un comportement indéfini (sauf pour "%p" ). Ce n'est donc pas portable, et il ne faut pas s'amuser à passer des NULL à printf() avec "%s".
 
Dans la norme, on lit :  

Citation :


7.19.6.1 The fprintf function
<...>
s If no l length modifier is present, the argument shall be a pointer to the initial
element of an array of character type
.240) Characters from the array are
written up to (but not including) the terminating null character. If the
precision is specified, no more than that many bytes are written. If the
precision is not specified or is greater than the size of the array, the array shall
contain a null character.
--------------------
240) No special provisions are made for multibyte characters.


Il n'est pas écrit que NULL est accepté (shall indique une obligation dans ce texte, c'est expliqué au début de la norme). Je confirme donc que le comportement est indéfini avec NULL.

Message cité 1 fois
Message édité par Emmanuel Delahaye le 31-01-2007 à 19:37:42

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-01-2007 à 20:07:40    

Emmanuel Delahaye a écrit :

Non. A ma connaissance (je vais quand même vérifier), ça ne va pas du tout. Le fait que NULL soit géré avec "%s" est un effet direct de la QoI (Quality of Implementation). Pas du tout du langage C pour lequel c'est un comportement indéfini (sauf pour "%p" ). Ce n'est donc pas portable, et il ne faut pas s'amuser à passer des NULL à printf() avec "%s".


 
Yes, je suis d'accord, c'était juste de l'humour. Un bon programmeur est un programmeur qui sait ce qu'il envoie quand il l'envoie.
 
De toute façon, il y a le bon programmeur, et le mauvais programmeur:

  • le mauvais programmeur, il passe n'importe quel pointeur à printf("%s" )
  • le bon programmeur, il passe n'importe quel pointeur à printf("%s" ) mais c'est un bon programmeur

[:ddr555]
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 31-01-2007 à 21:33:25    

Emmanuel Delahaye a écrit :

Citation :


Ah et bien la prof nous avait pourtant clairement expliquer qu'un pointeur s'adaptait a la taille demander..

 
Change de prof, et vite. Je donne des cours de C, des vrais, ça t'intéresse ?

Il y a malheureusement toujours une marge entre ce qu'un prof explique et ce que l'élève comprend ...
Par contre je suis d'accord qu'il y a un problème avec le new dans un programme C (pas C++ comme je l'avais écrit précédemment)


Message édité par Trap D le 01-02-2007 à 08:36:56
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed