258 lines
9.3 KiB
C
258 lines
9.3 KiB
C
//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);}
|
||
}
|
||
else 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[9];
|
||
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)
|
||
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[8]; //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-1] & 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 %c %c", b, b[0],b[7]);
|
||
printf("\n");
|
||
}
|
||
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;
|
||
}
|