AngoLinux

Calcolo della parità trasversale pari o dispari di una stinga

- A cura del Prof. Stefano Salvi -


Passiamo al calcolo della partità trasversale dei singoli codici di una stringa. È l'occazione per far sperimentare altre operazioni bit a bit e maschere di bit.

Il testo dell'esercizio è il seguente:

Scrivere un programma C che legga da tastiera una stringa di un massimo di 20 caratteri e chieda all'utente che parità vuole che venga calcolata. Il programma poi calcolerà la parità richiesta per ognuno dei codici introdotti e correggerà quelli con parità diversa dal richiesto. Il programma stamperà i codici modificati.
Suggerimenti
  • Per leggere una stringa da tastiera si può usare la funzione gets (<buf>). Questa funzione non conosce però il numero di caratteri disponibili nel buffer <buf>, quindi l'utente può introdurre più caratteri di quanti sono disponibili, creando gravi errori.
    È allora più opportuno utilizzare la funzione fgets (<buf>, <dimensione buf>, stdin) che fà esattamente la stessa cosa (legge una stringa da stdin, vale a dire da tastiera), ma non legge più caratteri di <dimensione buf>, evitando il problema.
  • Per cambiare la parità di un numero dobbiamo cambiare il valore di uno dei suoi bit. Il bit da cambiare è sempre il bit 7 (il più significativo). Per modificarlo possiamo utilizzare l'operazione EXCLUSIVE OR (operatore ^). Se facciamo l'exclusive or tra il nostro codice ed una maschera di bit che contenga tutti i bit a 0, eccetto il bit 7, il bit 7 del nostro codice verrà invertito, mentre tutti gli altri saranno lasciati immutati. Questo è più opportuno che impostare ad 1 il bit 7 del codice, in quanto questo bit potrebbe essere già ad 1, e l'operazione non darebbe il risultato voluto.

Una possibile soluzione è la seguente:
// Tizio - Pinco - 3°AIN - 05/04/2002
// Parità trasversale pari o dispari di una stinga 

#include <stdio.h>

#define DIM 20

int cambpar(int car);	// Inverte il bit piu' significativo del codice
			// per cambiarne la parita', ritorna il carattere cambiato
int numuno (int a);	// Conta il numero di bit ad 1 del codice a

main()
{
int i;		// Indice del carattewre da esaminare
int car;	// Carattere corretto, dopo il cambio di parita'
int par;	// Parita' desiderata
int d;		// Numero di bit ad 1 del codice corrente
char str[DIM];	// Stringa su cui calcolare la parita'

  printf("Inserisci una stringa: \n");
  // Usa fgets invece che gets per poter indicare la lunghezza massima della stringa
  fgets(str, DIM, stdin);

  do{
    printf("Tipo di parita' (0 = pari, 1 = dispari): ");
    scanf("%d",&par);
  }while(par<0 || par>1);

  for(i=0;str[i]!='\0';i++)	// Per ogni carattere della stringa
  {
    d=numuno(str[i]);		// Calcolo il numero di bit ad 1 del codcie
    if(d%2 != par)		// Se la parita' e' diversa dalla richiesta
    {
      car = cambpar(str[i]);	// Cambia la partia'
      printf("%x (%c) viene cambiato con %x\n",str[i],str[i],car);
      str[i] = car;		// E ripone il carattere corretto
    }
  }
}

/* Conta il numero di bit ad 1 del codice a
 * Ritorna il numero di bit contati
 */
int numuno(int a)
{
int i;			// Indice bit
int dist;		// Numero bit ad 1

  dist=0;		// Inizialmente il numero e' zero
  for(i=0;i<8;i++)	// Per ogni but del byte
  {
    if(a & 1)		// Se il bit 0 e' ad 1
    {
      dist++;		// Lo conto
    }
    a=a>>1;		// Quindi lo scarto e passo al prossimo
  }
  return dist;		// Restituisco il conteggio
}

/* Inverte il bit piu' significativo del codice per cambiarne la parita'
 * ritorna il carattere cambiato
 */
int cambpar(int car)
{
  // Fa' l'Exclusive Or del carattere con una maschera con il bit 7 ad 1
  return car ^ 128;
}

Per provare il programma, scaricare il sorgente, compilarlo con il comando cc parita.c ed eseguirlo con il comando ./a.out.


[Home Page dell'ITIS "Fermi"] [Indice Terza] [Precedente] [Successivo]

© Ing. Stefano Salvi - Released under GPL licence