Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

BUFFER CIRCULAIRE


Information sur la source

Catégorie :Fichiers / Disque Classé sous : buffer, circulaire, dadamagouil, vujica, dario Niveau : Expert Date de création : 07/02/2007 Date de mise à jour : 08/02/2007 09:28:26 Vu : 6 839

Note :
4,5 / 10 - par 2 personnes
4,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (7)
Ajouter un commentaire et/ou une note


Description

J'ai remarqué qu'il n'y avait pas de source sur les buffers circulaires. Etonnant pourtant c'est quelque chose à savoir. C'est vrai que le raisonnement n'est pas simple en lui même mais en le principe est d'allouer une memoire et stocker des données à l'intérieur en boucle. ce ki veut dire que une fois arrivà la fin de la mémoire on repart au debut. Si vous aimez les pointeurs vous allez adorer
 

Source

  • #include <stdio.h>
  • #include <malloc.h>
  • #include <conio.h>
  • #include <string.h>
  • typedef struct
  • {
  • char *debut;
  • char *fin;
  • char *producteur;
  • char *consommateur;
  • } CIRC;
  • CIRC * open_circ(int taille);
  • int get_circ(CIRC *B);
  • int put_circ(CIRC *B, int c);
  • void main (void)
  • {
  • CIRC * Buffer;
  • int c;
  • char choix; // Variable qui contiendra le choix de l'opération à effectuer
  • // Ouverture d'un buffer circulaire
  • Buffer = open_circ(20);
  • do
  • {
  • printf("\t\t\t buffer circulaire\n\n\n");
  • printf("\t 1. Ajouter 1 caractère\n");
  • printf("\t 2. Lire un caractère\n");
  • printf("\t 3. Quitter\n\n\n");
  • printf(" Faire votre choix svpl ? ");
  • fflush(stdin);
  • scanf("%c",&choix);
  • switch(choix)
  • {
  • case '1' :
  • // Ajouter 1 caractère
  • printf("Entrer un caractère : ");
  • fflush(stdin);
  • scanf("%c", &c);
  • if(put_circ(Buffer, c)== EOF)
  • printf("Le buffer est plein!\n");
  • break;
  • case '2' :
  • // Lire un caractère
  • c = (char)get_circ(Buffer);
  • if( c != EOF)
  • printf("Le caractère lu est : %c\n",c);
  • else
  • printf("Le buffer est vide!\n");
  • break;
  • case '3' : printf("Au revoir");break;
  • default : printf("Vérifier votre choix svpl ! \n");
  • }
  • }
  • while( choix != '3' ) ;
  • }
  • CIRC * open_circ(int taille)
  • {
  • CIRC * B;
  • B = (CIRC *)malloc(taille);
  • if(B == NULL)
  • {
  • return(EOF);
  • }
  • else
  • {
  • B->debut = (char *)B+(sizeof(CIRC));
  • B->consommateur = (char *)B+(sizeof(CIRC));
  • B->producteur = (char *)B+(sizeof(CIRC));
  • B->fin = (char *)B+taille;
  • }
  • return(B);
  • }
  • int get_circ(CIRC *B)
  • {
  • if(B->consommateur == B->producteur)
  • return(EOF);
  • if(++(B->consommateur)==B->fin)
  • B->consommateur = B->debut;
  • return (*(B->consommateur));
  • }
  • int put_circ(CIRC *B, int c)
  • {
  • char *p;
  • p=B->producteur + 1;
  • if (p == B->fin)
  • {
  • p = B->debut;
  • }
  • if (p == B->consommateur)
  • {
  • return(EOF);
  • }
  • * p = c;
  • B->producteur = p;
  • return (c);
  • }
#include <stdio.h>
#include <malloc.h>
#include <conio.h>
#include <string.h>

typedef struct
{
			char *debut;
			char *fin;
			char *producteur;
			char *consommateur;
} CIRC;


CIRC * open_circ(int taille);
int get_circ(CIRC *B);
int put_circ(CIRC *B, int c);


void main (void)

{
	CIRC * Buffer;
	int  c;
	char choix; // Variable qui contiendra le choix de l'opération à effectuer

	// Ouverture d'un buffer circulaire
	Buffer = open_circ(20);

	do
	{
		printf("\t\t\t   buffer circulaire\n\n\n");
		printf("\t      1. Ajouter 1 caractère\n");
		printf("\t      2. Lire un caractère\n");
		printf("\t      3. Quitter\n\n\n");
		printf("  Faire votre choix svpl ? ");


		fflush(stdin);
		scanf("%c",&choix);
		switch(choix)
		{
			case '1' :
			// Ajouter 1 caractère
				printf("Entrer un caractère : ");
				fflush(stdin);
				scanf("%c", &c);
				if(put_circ(Buffer, c)== EOF)
					printf("Le buffer est plein!\n");

			break;

			case '2' :
			// Lire un caractère
				 c = (char)get_circ(Buffer);
				 if( c != EOF)
					printf("Le caractère lu est : %c\n",c);
				 else
					printf("Le buffer est vide!\n");
			break;

			case '3' : printf("Au revoir");break;

			default  : printf("Vérifier votre choix svpl ! \n");
		}
	}
	while( choix != '3' ) ;
}
CIRC * open_circ(int taille)
{
	CIRC * B;
	B = (CIRC *)malloc(taille);
	if(B == NULL)
	{
		return(EOF);
	}
	else
	{
		B->debut = (char *)B+(sizeof(CIRC));
		B->consommateur = (char *)B+(sizeof(CIRC));
		B->producteur = (char *)B+(sizeof(CIRC));
		B->fin = (char *)B+taille;

	}
	return(B);
}
int get_circ(CIRC *B)
{
	if(B->consommateur == B->producteur)
		return(EOF);
	if(++(B->consommateur)==B->fin)
		B->consommateur = B->debut;
	return (*(B->consommateur));

}
int put_circ(CIRC *B, int c)
{
	char *p;
	p=B->producteur + 1;
	if (p == B->fin)
	{
		p = B->debut;
	}
	if (p == B->consommateur)
	{
		return(EOF);
	}
	* p = c;
	B->producteur = p;
	return (c);
}

Conclusion

J'avoue que c'est pas simple à comprendre. mais prenez le temps de le faire. ceci pourra vous servire un jour
 

Historique

08 février 2007 09:28:27 :
Faute de frappe

Commentaires et avis

signaler à un administrateur
Commentaire de erazor le 08/02/2007 08:22:04

Un peu léger en commentaires je trouve, cela rend encore moins simple la comprehension.

signaler à un administrateur
Commentaire de Clem le 11/02/2007 17:32:43

Je confirme ce que erazor dit, les commentaires sont clairement trop peux nombreux surtout qu'il n'est pas difficile de commenter un code aussi court. Tu aurais pu expliquer au moins le principe, ce que tu entends par consommateur et par producteur. Sans parler du fait que la description est à relire avant de poster une news, car ici elle ne comporte pas que des fautes, mais des manques de virgules, des points et le pire des mots.

Et puis, c'est bien beau le malloc, mais les free ils sont passés où ? Le C n'a jamais eu de garbage collector et je ne sais vraiment pas d'où vient cette mauvaise manie de ne jamais désallouer la mémoire allouée!

signaler à un administrateur
Commentaire de dadamagouil le 11/02/2007 22:34:39

Je sais quil manque des commentaires, mais par contre je vois pas ou il manque des points ni des points virgules. en plus ma source a été compilé sans erreur. le malloc je l'avoue c'est une mauvaise habitude. Et pour conclur je n'ai pas eu le temps de faire les commentaires je comptais les faire par la suite mais j'ai pas que ça à faire. désolé

signaler à un administrateur
Commentaire de Clem le 12/02/2007 11:41:10

juste les deux choses qui m'ont parues les plus gênantes dans l'introduction :
"Etonnant pourtant" le lecteur n'est pas tenu de savoir qu'il faut une pause entre ces deux mots quand il lit.
"mais en le principe" il semble manquer le mot "fait"

mais après tout on est pas là pour juger ton Français, plus le code.
j'ai d'ailleurs une chose de plus à noter à ce niveau, puisque je viens seulement de remarquer que tu utilise ton consommateur et ton producteur pour déterminer la 'fin' du buffer, mais pourtant tu utilise la valeur EOF dans tes fonctions pour laisser à l'utilisateur la possibilité de savoir quand le buffer est finit.
Mais et si jamais l'utilisateur voulait créer un buffer circulaire, pour gérer du son comme c'est souvent le cas dans ce type de tampons ? La donnée du son et bien souvent une valeur arbitraire, pouvant contenir la valeur de EOF justement!
En résumé, quelqu'un utilisant ce code tel quel et gérant un tampon de son, peut de façon aléatoire voir son programme déconner puisque il pourrait croire que le tampon serait finit sans qu'il le soit, soit une perte de données.
Pourquoi n'utilise pas plutôt un modèle de fonction get, dont l'entête serait plutôt :
int get_circ(CIRC *B, int * dest);

Et à la place de renvoyer la valeur, renverrait le status (0 en cas de réussite, 1 en cas d'echec par exemple), et prendrait en argument de sortie 'dest', l'octet à lire.
Rien ne changerait du côté de la fonction put, juste ses valeurs de retour, et ce n'est pas plus compliqué puisque la structure s'y prête déjà. Et après tout cela tu pourras commencer à juger le code source comme de niveau "intermédiaire" (il est très éloigné des codes experts que l'on peut trouver sur ce site)

Pour les commentaires, si je le reproche c'est parce que j'ai moi aussi la mauvaise habitude de ne pas en faire, mais comme tout programmeur, on sait que "plus-tard" se résume bien souvent à jamais.
Ah et les .h, évites aussi d'inclure sans savoir ceux que tu connais, ça fait un peu "tâche" dans un code source. Normalement, stdio.h et stdlib.h devraient te suffirent.

En espérant pouvoir noter en remontant la moyenne de cette source.

signaler à un administrateur
Commentaire de dadamagouil le 12/02/2007 14:50:23

Pas mal ton analyse. Je pense que tu as l'habitude d'en faire. Je veux juste préciser quelques choses. La fin du buffer est marqué par le pointeur fin. On positionne le pointeur debut au debut, le nom me semble assez explicite, et le pointeur fin ben à la fin.

Aussi, le buffer est un buffer circulaire, ceux qui veut dire en d'autre terme qu'il n'as pas de fin, en fait le pointeur fin sert à indiquer à la fonction qu'il faut retourner au debut et en aucun cas de lui indiquer que le buffer est plein. le buffer est plein que quand le consommateur une mémoire avant le producteur. Le mot circulaire est très important dans l'interprétation de la source.

Merci de critiquer ma source. Si elle te plait pas personne ne t'interdit de créer la tienne et de la poster sur le site. Cette source et la comme exemple, si une personne veut l'utiliser pour gérer du son c'est son droit. Elle aura déjà les base. Je le répète encore une fois cette source est là pour montrer le fonctionnement des buffer circulaire. La personne qui est interessé la récupère et la modifie à sa convenance. Toi si t'en a pas besoin va voir ailleur. Si ton but est de rabaisser les autres je crois que tu n'a rien a foutre ici. Ha oui en fait les .h j'en déclare plusieurs pour la simple raison que si j'ai besoin d'autre fonction je me fais pas chier à les déclarer.

A oui pour finir ton int get_circ(CIRC *B, int * dest); est inutile dans cette source. Ca compliquerait la compréhension des buffers.

signaler à un administrateur
Commentaire de diabolo38 le 21/12/2007 14:02:59 4/10

Pas intuitif les params pour open de CIRC la taille alouee n'est pas le nombre d'element dans ton buffer circulaire qui est taille - sizeof(CRIC)
Tu as en plus un petit bug si taile est < sizeof(CRIC).
Danc ce dernier cas tu n'as pas de place pour le stockage des donnees, tes  pointeur de control vont aussi se telescper pour ne pas dire se mordre la queues  :)
Autre detail sur l'open circ elle devrais retourner NULL en cas d'ehec pas EOF qui est un pointeur valid.

Perso je preffere gere un buffer circulaire via index (ou offset c'est idem) plutot que les pointeurs c'est surtourt pour eliminer les if dans la manipulation des pointeur sur entree sortie de donnes et le test de rebouclage typiquement
  Buffer[In]=Data
  In= (In+1)%TailleBufer
Si tu choisi TailleBuffer = 2^N alors le modulo se limite a un '&'(2^N -1) encore plus rapide que les modulo ... ex N =8
   Buffer[In++]=Data;
   In&=0xFF;

Dans un souci de perf comme la gestion d'une fifo sur interrupt cela peu avoir son importance...

signaler à un administrateur
Commentaire de dadamagouil le 21/12/2007 19:40:10

En fait cette source a surtout pour effet de démontrer l'utilisation des pointeurs. Vu que les pointeurs ne sont pas simples d'utilisation.

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Programme Crasher [ par Kephren ] Salut, je viens demander de l'aide à propos de mon programme. En fait il marche très bien mais depuis que j'ai rajoutée du code, une fois compilé, je E/S sur port série [ par Gaelle ] SalutMon prog (sous VC++6) gère le port serie pour l'envoi et la reception d'info. J'utilise pour cela les fonctions _outp(PORT, int) et _inp(PORT)Mon [allegro]Pb de base [ par kjus ] Valla g installé la lib pour vc++6seulement voila mon premier code allegro :et pas moyen d'afficher quoi que ce soit (g aussi essayé de faire buffer=l Transfert d'un fichier d'un ftp [ par header ] Salut,J'ia besion d'aide : pour que tlm puisse comprendre voici mon source : char buffer[DWN_BUFFER]; // c un define 4096unsigned int count = DWN_BUFF Caractères spéciaux [ par redpooka ] Comment faire je lis un fichier et je met son contenu dans une string, or quand je l'affiche les caractères spéciaux (é, ç...) ne marchent pas ? Comme Question sur les pointeurs [ par Darkneon ] Voici un programme tiree de "Simple C++"#include &lt;string.h&gt;#include &lt;iostream.h&gt;class Court{private: //attributes char * Buffer avec WriteFile ??????????? [ par nanalye ] Bonjour tout le monde !J'ai regardé sur le forum ce qui était mis sur ce sujet mais je n'ai pas tout compris.Je dois envoyer des entiers par le biais probleme serveur-client [ par dorian2031 ] ben voila le probleme, dans mon serveur-clientmon client envoi bien un message avec : char buffer[1024]="slt a toi\0";.... send(serveur,buffer,1024, Vider le RECV Buffer d'une Socket ? [ par Kikyo ] Oauip c'est possible de vider le Buffer qui recoit les données, d'une Socket ? taille chaine de char [ par langedechu ] Salut , voila mon prob (je sais plus comment faire) :j'ai une variable : const char *buffer; et j aimerais savoir le nombre de caractere stocker dans


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,530 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.