Esercitazione 12 – Liste – 17-12-2020

Premi qui per scaricare il PDF

[adinserter block="5"]

Esercizio 1

Scrivere un programma che permetta di acquisire matrici di interi di dimensioni non note a priori e di memorizzarle su disco. Il programma deve eseguire le seguenti operazioni:

  • Chiedere all’utente di inserire le dimensioni della matrice (dimensioni minime 1×1);
  • Allocare la memoria per contenere la matrice di numeri interi mediante una funzione creaMatrice che restituisce un puntatore alla memoria allocata le cui dimensioni sono passate come parametri;
  • Chiedere all’utente di inserire i valori della matrice mediante una procedura inserisciMatrice;
  • Memorizzare su disco la matrice acquisita (e tutte le informazioni necessarie per ricostruirla) mediante una procedura salvaMatrice.
#include <stdio.h>
#include <stdlib.h>
#define MINROW 1 
#define MINCOL 1 

int *creaMatrice (int, int); 
void inserisciMatrice (int *, int, int); 
void salvaMatrice (int*, int, int); 
 
int main()
{
	int *m; 
	int numRow, numCol; 
	 
	do
	{ 
		printf("inserire il numero di righe: "); 
		scanf("%d", & numRow); 
	 
		if (numRow < MINROW) 
			printf("numero del valore non corretto"); 
	}while (numRow < MINROW); 
	 
	do
	{ 
		printf("inserire il numero di colonne: "); 
		scanf("%d", & numCol); 
	 
		if (numCol < MINCOL) 
			printf("numero del valore non corretto"); 
	}while (numCol < MINCOL); 
	 
	m = creaMatrice (numRig, numCol); 
	 
	if(m == NULL) 
		printf("errore nella creazione della matrice"); 
	else
	{ 
		inserisciMatrice (m, numRig, numCol); 
		salvaMatrice (m, numRig, numCol); 
	 
		free (m); 
	}
	return 0;
}

int * creaMatrice (int numRow, int numCol)
{
	int *m;
	m = (int *)malloc(sizeof(int) * numRow * numCol);
	return m;
}

void inserisciMatrice(int *m, int numRow, int numCol)
{
	int i,j;

	for (i = 0; i < numRow; i++)
		for (j = 0; j < numCol; j++)
		{
			printf("\\nInserire l'elemento riga %d, colonna &d:", i + 1, j+1);
			scanf("%d", (m + (i * numCol) + j)); //scanf("%d", &m[i][j]);
		}
}

void salvaMatrice(int *m, int numRow, int numCol)
{
	int i;
	FILE *fp;
	fp = fopen ("m.txt", "w");
	if (fp == NULL)
		printf("\\nErrore di accesso al file");
	else
	{
		fprintf(fp, "%d\\n", numRow);
		fprintf(fp, "%d\\n", numCol);
	
		for (i = 0; i < numRow * numCol; i++)
			fprintf(fp, "%d\\n", *(m+i));

		if (fclose(fp) == EOF)
			printf("\\nErrore durante la chiusura del file");
	}
}

STAMPARE UNA MATRICE RIGA PER RIGA

for (i = 0; i < numRow; i++)
{
	for (j = 0; j < numCol; j++)
		printf("%d\\t", *(m + (i * numRow) + j));

	printf("\\n");
}
[adinserter block="7"]

Esercizio 2

Definire un tipo di dato che ha lo scopo di descrivere uno studente e che possa diventare un elemento di una lista semplice. Uno studente è definito da:

  • Nome (stringa di lunghezza massima 30 caratteri];
  • Media voti (numero intero compreso tra 1 e 30).

Scrivere quindi un programma in C che acquisisce in una lista i dati di un numero non definito a priori di studenti. Al termine dell’immissione il programma deve visualizzare tutti i nomi che hanno una media maggiore o uguale a 25.

Note per l’implementazione:

  1. La modalità di terminazione dell’immissione è lasciata al progettista. Implementare e commentare la scelta effettuata;
  2. Per inserire gli studenti nella lista, eseguire un’inserimento in testa.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLEN_NOME 30

typedef struct studente
{
	char nome [MAXLEN_NOME +1];
	int media;
	struct studente *next;
}studente;

int main()
{
	studente *s, *elem;
	char nome [MAXLEN_NOME +1];
	int fineInserimento;
	/*L'utente può terminare l'inserimento inserendo
	come nome utente la parola 'fine'*/

	fineInserimento = 0; 
	s = NULL;
	do
	{
		printf("\\nInserire il nome dello studente ('fine' per terminare): ");
		gets(nome);
		getchar();

		if(strcmp("fine", nome) == 0)
			fineInserimento = 1;
		else
		{
			if (elem = (studente*)malloc(sizeof(studente))) //elem = (studente*)malloc(sizeof(studente));
			{
					do
					{
						printf("Inserisci la media\\n");
						scanf("%d", &elem->media);

						if(elem -> media < 1 || elem -> media > 30)
							printf("\\nValore non corretto");
					} while (elem -> media < 1 || elem -> media > 30);

					strcpy(elem->nome, nome);
					elem -> next = NULL;

					if (s == NULL)
						s = elem;
					else
					{
						elem -> next = s;
						s = elem;
					}
			}		
		}
	}while (!fineInserimento); //fineInserimento == 0

	for (elem = s; elem; elem = elem -> next) //elem != NULL
		if(elem->media >= 25)
			printf("\\n%s:%d", elem-> nome, elem->media);

	//Liberare ogni elemento nella lista
	while(s) //s != NULL 
	{
		elem = s;
		s = s-> next;
		free(elem);
	}
	
	return 0;
}
[adinserter block="7"]

Esercizio 3

Siano L1 e L2 due liste di interi (struttura con un campo intero e uno puntatore) dichiarate come variabili globali. Scrivere una funzione che effettua la concatenazione di L1 e L2 e restituisce 1 in caso di successo, 0 nel caso entrambe le liste siano vuote. La concatenazione si ottiene attaccando in fondo alla lista L1 gli elementi della lista L2.

Scrivere quindi un programma in C che legge da due file (in1.txt e in2.txt) i dati da inserire nelle due liste di interi (utilizzare l’inserimento in coda), esegue la concatenazione e stampa e video la lista ottenuta.

#include <stdio.h>
#include <stdlib.h>

#define IN1 "in1.txt"
#define IN2 "in2.txt"

typedef struct L1
{
  int intero1;
  struct L1 *next;
}L1,L2,L3;

L1 *testa1;
L2 *testa2;

void concat();

int main() {
  FILE *fp1, *fp2;
  L1 *t1;
  L2 *t2;

  fp1 = fopen(IN1, "r");
  fp2 = fopen(IN2, "r");
  if (fp1 == NULL)
  {
    printf("Errore, impossibile aprire il file 1\n");
    fclose(fp2);
  }
  else if (fp2 == NULL)
  {
    printf("Errore, impossibile aprire il file 2\n");
    fclose(fp1);
  }

  else
  {
    while(!feof(fp1))
    {
        if(!testa1) //Se la testa è vuota => testa == NULL
		    {
          testa1 = (L1*) malloc (sizeof(L1));
          fscanf(fp1, "%d\n", &testa1->intero1);
          testa1 -> next = NULL;
		    }
        else
        {
          t1 = testa1;
          while (t1 -> next != NULL)
            t1 = t1 -> next;
          t1 -> next = (L1*)malloc(sizeof(L1));
          t1 = t1->next;
          fscanf(fp1, "%d\n", &t1->intero1);
        }
    }

    while(!feof(fp2))
    {
        if(!testa2) //Se la testa è vuota => testa == NULL
		    {
          testa2 = (L2*) malloc (sizeof(L2));
          fscanf(fp2, "%d\n", &testa2->intero1);
          testa2 -> next = NULL;
		    }
        else
        {
          t2 = testa2;
          while (t2 -> next != NULL)
            t2 = t2 -> next;
          t2 -> next = (L2*)malloc(sizeof(L2));
          t2 = t2->next;
          fscanf(fp2, "%d\n", &t2->intero1);
        }
    }
  }
  if(fclose(fp1) == EOF)
    printf("Errore nella chiusura del file 1 \n");
  if(fclose(fp2) == EOF)
    printf("Errore nella chiusura del file 2\n");

  printf("I numeri acquisiti lista 1 sono:\n");
  t1 = testa1;
  while(t1!=NULL) {
    printf("%d ", t1 -> intero1);
    t1=t1->next;
  }

  printf("\nI numeri acquisiti lista 2 sono:\n");
  t2 = testa2;
  while(t2!=NULL) {
    printf("%d ", t2 -> intero1);
    t2=t2->next;
  }

  concat();

  return 0;
}

void concat()
{
  printf("\n");
  L3 *t, *testa3;
	
  t = (L3*)malloc(sizeof(L3));
  testa3 = (L3*)malloc(sizeof(L3));

  testa3 = testa1;
  for (t = testa3; t->next != 0; t = t -> next);
  t->next = testa2;

  printf("La stringa concatenata e': ");
  while(testa3 != NULL) {
    printf("%d ", testa3 -> intero1);
    testa3=testa3->next;
 }
}
[adinserter block="7"]

Premi qui per scaricare il PDF