laboProgra/colin22.c

259 lines
9.5 KiB
C
Raw Permalink Blame History

//Compl<70>tez le programme en respectant les consignes donn<6E>es en commentaires.
//Biblioth<74>ques (2 pts)
#include <stdio.h>
#include <conio.h>
//D<>finition d'une constante N de valeur 10 (2 pts)
#define N 10
//#define __DEBUG__
//Prototypes des fonctions d<>finies par apr<70>s (7 pts)
FILE* OuvrirFichier ();
void EncoderNomFichier (char[]);
char ChaineVersOctet (char[]);
void LireDonnees (FILE*, char[]);
void AfficherDonnees (char[]);
void CorrigerDonnee (char[], int);
int ParitePaire (char);
int main()
{
int i, erreur=0;
//D<>claration d'un pointeur fichier permettant de manipuler un fichier, initialis<69>
//<2F> NULL (2 pts)
FILE* fichier = NULL;
//D<>claration d'un tableau tab de N <20>l<EFBFBD>ments de 8 bits (2 pts)
char tab[N];
//Le pointeur fichier prend la valeur retourn<72>e par OuvrirFichier (2 pts)
fichier = OuvrirFichier ();
//Si la valeur du pointeur fichier indique que le fichier a pu <20>tre ouvert (1 pt)
if (fichier != NULL)
{//Appel de la fonction LireDonnees (2 pts)
LireDonnees(fichier, tab);
//Fermeture du fichier (1 pt)
fclose (fichier);
printf("\nDonnees lues :");
//Affichage en binaire des N <20>l<EFBFBD>ments de tab (1 pt)
AfficherDonnees (tab);
for (i=0; i<N; i++)
{//Tant que ParitePaire retourne "faux" pour l<><6C>l<EFBFBD>ment i de tab (3 pts)
//while (ParitePaire(tab[i] == 0))
while (!ParitePaire(tab[i])) //Corection
{//Appel de la fonction CorrigerDonnee pour l<><6C>l<EFBFBD>ment i de tab (2 pts)
CorrigerDonnee(tab,i);
erreur++;
}
}
//Si erreur est "vrai" (1 pt)
if (erreur)
{printf("\nDonnees corrigees :");
//Affichage en binaire des N <20>l<EFBFBD>ments de tab (1 pt)
AfficherDonnees (tab);}
}
printf("Au revoir!");
getch();
return 0;
}
//Type de valeur retourn<72>e par la fonction OuvrirFichier (1 pt)
FILE* OuvrirFichier()
{
int ouvrir = 1;
//D<>claration d'un caract<63>re reponse et d'une cha<68>ne nomfichier pouvant stocker
//un nom de 250 caract<63>res (2 pts)
char reponse;
char nomfichier[251];
//D<>claration d'un pointeur fichier permettant de manipuler un fichier (1 pt)
FILE* fichier;
do
{
//Appel de la fonction EncoderNomFichier (1 pt)
EncoderNomFichier(nomfichier);
//Appel de la fonction d<>finie dans stdio.h permettant d'ouvrir en mode
//"lecture seule" le fichier texte dont le nom est enregistr<74> dans nomfichier
//et sauvegarde de la valeur renvoy<6F>e par cette fonction dans le pointeur
//fichier (4 pts)
fichier = fopen (nomfichier, "r");
//Si la valeur du pointeur fichier indique que le fichier n<>a pas pu <20>tre ouvert
//(1 pt)
if (fichier == NULL)
{
printf("Fichier introuvable");
printf("\nNouvel essai?(o/n) ");
//Vider la m<>moire clavier et saisir la reponse de l'utilisateur (3 pts)
fflush(stdin);
scanf ("%c", &reponse);
//Si la reponse n<>est ni o minuscule ni O majuscule, ouvrir prend la
//valeur "faux" (3 pts)
if (reponse !='o' && reponse !='O')
ouvrir = 0;
}
}while (fichier == NULL && ouvrir==1);
//Tant que la valeur du pointeur fichier indique que le fichier n<>a pas pu <20>tre
//ouvert et que ouvrir est "vrai" (2 pts)
return fichier;
}
//La fonction EncoderNomFichier re<72>oit en argument une cha<68>ne de caract<63>res
//nomfichier. Elle ne retourne aucune valeur. (2 pts)
void EncoderNomFichier(char nomfichier [251])
{
printf("Nom complet du fichier (avec chemin d'acces):\n");
//Vider la m<>moire clavier et enregistrer le nom de fichier encod<6F>
//dans la cha<68>ne nomfichier (2 pts)
fflush (stdin);
gets (nomfichier);
}
//La fonction ChaineVersOctet re<72>oit en argument une cha<68>ne de caract<63>res chaine.
//Elle retourne une variable cod<6F>e sur un octet. (2 pts)
char ChaineVersOctet(char chaine[9])
{
int i;
//D<>claration et initialisation des variables octet et masque (2 pts)
char octet = 0;
char masque = 1;
//Boucle pour parcourir tous les <20>l<EFBFBD>ments de l<>octet, du bit de poids faible au
//bit de poids fort (3 pts)
for (i=7; i>=0; i--)
{
//Si l<><6C>l<EFBFBD>ment i de chaine est le caract<63>re 1, positionner le bit
//correspondant de la variable octet <20> 1, sinon le laisser <20> 0. (4 pts)
if (chaine[i] == '1')
octet = octet|masque;
//D<>caler masque pour traiter le bit suivant (1 pt)
masque<<=1;
}
return octet;
}
//La fonction LireDonnees re<72>oit en arguments un pointeur fichier permettant
//de manipuler un fichier et un tableau tab dont chaque <20>l<EFBFBD>ment est une donn<6E>e
//cod<6F>e sur 8 bits. Elle ne retourne aucune valeur. (3 pts) G:\PROJET_FINAL_HTML\progra\colin22.txt
void LireDonnees (FILE *fichier, char *tab)
{
int i;
char donnee[10];
char *p;
for(i=0; i<N; i++)
{
#ifdef __DEBUG__
printf("DEBUG : I : %d\n",i);
#endif
//Lecture d<>une cha<68>ne de caract<63>res dans le fichier et enregistrement
//dans donnee. On suppose que le fichier ne comporte que des mots de 8 caract<63>res
//0 ou 1 repr<70>sentant des octets binaires. (2 pts)
char * ptf = fgets(donnee, sizeof(donnee), fichier);
p = strchr(donnee, '\n');
if(p)
*p='\0';
#ifdef __DEBUG__
printf("DEBUG : I : %d\n",i);
#endif
//Assignation <20> l<><6C>l<EFBFBD>ment i de tab de la valeur convertie en octet de la donnee
//lue (2 pts)
#ifdef __DEBUG__
printf("DEBUG %d: DONNE LUE : %s\n",i, donnee);
#endif
tab[i] = ChaineVersOctet(donnee);
#ifdef __DEBUG__
printf("DEBUG %d: DONNE LUE CONVERTIE EN OCTECT: %c\n",i, tab[i]);
#endif
}
}
//La fonction AfficherDonnees re<72>oit en argument un tableau tab dont chaque <20>l<EFBFBD>ment
//est une donn<6E>e cod<6F>e sur 8 bits. Elle ne retourne aucune valeur. (2 pts)
void AfficherDonnees(char tab[])
{//D<>claration et <20>ventuellement initialisation des variables locales (3 pts)
int i, j, m = 1;
char b[9]; //8 bit + \0 = 9
for(i=0; i<N; i++) //parcour tab d'octet
{
m = 1;
printf("\n%2d) ",i+1);
//Affichage en binaire de l<><6C>l<EFBFBD>ment i de tab (6 pts)
for (j=8; j>0; j--)
{
if (tab[i] & m)
{
#ifdef __DEBUG__
printf("DEBUG i%d j%d: DONNE tab[i] %c avec masque %x\n",i,j,tab[i], tab[i]&0xff&m);
#endif
b[j-1]='1';
}
else
{
#ifdef __DEBUG__
printf("DEBUG i%d j%d: DONNE tab[i] %c avec masque %x\n",i,j,tab[i], tab[i]&0xff&m);
#endif
b[j-1]='0';
}
m<<=1;
}
b[8]='\0';
printf ("%s", b);
}
printf("\n");
}
//La fonction CorrigerDonnee re<72>oit en arguments un tableau tab dont chaque <20>l<EFBFBD>ment
//est une donn<6E>e cod<6F>e sur 8 bits et un entier i. Elle ne retourne aucune valeur.
//(3 pts)
void CorrigerDonnee(char tab[N], int i)
{
char donnee[9];
printf("\nLa donnee %d est erronnee; veuillez la reencoder:", i+1);
//Vider la m<>moire clavier et saisir la valeur de donnee.(3 pts)
fflush (stdin);
gets(donnee);
//Remplacer l<><6C>l<EFBFBD>ment i de tab par la donnee r<>encod<6F>e convertie en octet. (2 pts)
tab[i] = ChaineVersOctet(donnee);
}
//La fonction ParitePaire re<72>oit un argument octet cod<6F> sur 8 bits. Elle retourne
//"vrai" ou "faux". (2 pts)
int ParitePaire (char octet)
{//D<>claration et <20>ventuellement initialisation des variables locales (3 pts)
int i, compteur = 0, masque = 1;
for (i=0; i<8; i++)
{//Si le bit i de l<>argument octet vaut 1, incr<63>menter la variable compteur
//d<>une unit<69> (3 pts)
if (octet & masque)
compteur++;
//D<>caler masque pour traiter le bit suivant (1 pt)
masque <<= 1;
}
//Si compteur est impair retourner "faux", sinon retourner "vrai" (2 pts)
if (compteur%2)
return 0;
else
return 1;
}