Programma sulle liste

di il
8 risposte

Programma sulle liste

Buongiorno, nel codice seguente ho dei problemi con il massimo. Nel senso che dovrei stampare il nome del disco con il costo massimo ma alla fine mi da errore di segmentazione, non riesco a capire dove ho sbagliato perché le altre funzioni funzionano bene (scusate il gioco di parole).

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
struct Tdisco {
		char nome[25];
		int numero_canzoni;
		int anno_di_uscita;
		float costo;
		};
typedef struct Tdisco Sdisco; 
struct SNodo {
		Sdisco disco;
		struct SNodo *next;
		};
typedef struct SNodo TNodo;
typedef TNodo *Tlista;

int menu();
Tlista crea_lista();
Sdisco leggi_dischi();
Tlista inserisci_disco(Tlista lista, Sdisco disco);
Tlista cancella_disco(Tlista lista, char elem[]);
TNodo* cerca(Tlista lista, char elem[]);
int maggiore_costo(TNodo *p);
void stampa_lista(Tlista lista);

int main(void)
{
	Tlista lista;
	int i,dim,scelta,max;
	char elem[25];
	TNodo* nodo;
	TNodo* succ;
	Sdisco disco;
	system("clear");
	lista=crea_lista();
	do {
		printf("\n Quanti dischi vuoi inserire: ");
		scanf("%d", &dim);
		getchar();
		if(dim<=0) printf("\n ***ERRORE***\n");
	   } while(dim<=0);
	do{			
		system("clear");
		scelta=menu();			
		switch(scelta) {
				case 0:
					printf("\n Stai per uscire. Premi un tasto per continuare...");
					getchar();
					break;

				case 1:
					for(i=0;i<dim;i++) {
								disco=leggi_dischi();
								lista=inserisci_disco(lista,disco);
							   }
					printf("\nPremi un tasto per continuare...\n");
					getchar();
					break;
				case 2:
					printf("\n Inserisci il disco da eliminare: ");
					scanf("%s", elem);
					getchar();
					lista=cancella_disco(lista, elem);
					printf("\nPremi un tasto per continuare...\n");
					getchar();
					break;
				
				case 3:
					printf("\n Inserisci il disco da cercare: ");
					scanf("%s", elem);
					getchar();
					nodo=cerca(lista, elem);
					if(nodo!=NULL) printf("\n **Disco trovato**\n");
					else printf("\n Disco non trovato!!\n");
					printf("\nPremi un tasto per continuare...\n");
					getchar();
					break;

				case 4:
					
					max=maggiore_costo(lista);
							
					printf("\nPremi un tasto per continuare...\n");
					getchar();
					break;
				
				case 5:
					stampa_lista(lista);
					printf("\nPremi un tasto per continuare...\n");
					getchar();
					break;

				default:
					printf("\n ***ERRORE***Inserisci un'altra scelta [0-5]...");
					scanf("%d", &scelta);
					getchar();
					break;
				}
	  } while(scelta!=0);
}

int menu()
{
	int scelta;
	printf("\n Questo programma ti permette di: \n");
	printf("\n -0.Esci dal programma\n");
	printf("\n -1.Inserisci disco\n");
	printf("\n -2.Elimina disco\n");
	printf("\n -3.Ricerca disco\n");
	printf("\n -4.Visualizzi il disco con il costo maggiore\n");
	printf("\n -5.Stampa dischi\n");
	printf("\n Inserisci qui la tua scelta...\n");
	scanf("%d", &scelta);
	getchar();
	return scelta;
}
Tlista crea_lista()
{
	return NULL;
}
Sdisco leggi_dischi()
{
	Sdisco disco;
	printf("\n Inserisci il nome del disco: ");
	scanf("%s", disco.nome);
	getchar();
	printf("\n Inserisci il numero di canzoni: ");
	scanf("%d", &disco.numero_canzoni);
	getchar();
	printf("\n Inserisci il costo: ");
	scanf("%f", &disco.costo);
	getchar();
	printf("\n Inserisci l'anno di uscita del disco: ");
	scanf("%d", &disco.anno_di_uscita);
	getchar();

	return disco;
}
Tlista inserisci_disco(Tlista lista, Sdisco disco)
{
	Tlista prec,succ,nuovonodo;
	prec=NULL;
	succ=lista;
	
	while((succ!=NULL) && (disco.costo>succ->disco.costo)) {
																			
								prec=succ;								
								succ=succ->next;
											}
	nuovonodo=(TNodo *)malloc(sizeof(TNodo));
	assert(nuovonodo!=NULL);
	nuovonodo->disco=disco;
	if(prec==NULL) {
			nuovonodo->next=lista;
			lista=nuovonodo;
			return lista;
			}
	else {
		prec->next=nuovonodo;
		nuovonodo->next=succ;
		return lista;
		}
}
Tlista cancella_disco(Tlista lista, char elem[])
{
	Tlista succ,prec;
	prec=NULL;
	succ=lista;
	while((succ!=NULL) && (strcmp(succ->disco.nome,elem)!=0)) {
									prec=succ;
									succ=succ->next;
								}
	if(succ!=NULL && (strcmp(succ->disco.nome,elem)==0)) {
								if(prec==NULL) {
										lista=succ->next;
										}
								else {
									prec->next=succ->next;
									}
								free(succ);
								}
	return lista;
}
TNodo* cerca(Tlista lista, char elem[])
{
	TNodo* succ;
	succ=lista;

	while(succ!=NULL && (strcmp(succ->disco.nome,elem)!=0)) {
									succ=succ->next;
								}
	if(succ!=NULL && (strcmp(succ->disco.nome,elem)==0)) {
								return succ;
								}
	else {
		return NULL;
		}
}
int maggiore_costo(TNodo *p)
{
	float max=INT_MIN;
	while(p!=NULL) {
			if(p->disco.costo > max) max=p->disco.costo;
			p=p->next;
			
			}
	printf("\n Il massimo è: %f\n", max);
	if(p->disco.costo==max)	printf("\n Il disco con il prezzo maggiore è: %s",p->disco.nome);	

	return max;

}
void stampa_lista(Tlista lista)
{
	Tlista succ;
	succ=lista;
	while(succ!=NULL) {
				printf("\nNome:%s\t", succ->disco.nome);
				printf("Numero canzoni:%d\t", succ->disco.numero_canzoni);
				printf("Costo:%f\t", succ->disco.costo);
				printf("Anno di uscita:%d\t", succ->disco.anno_di_uscita);
				succ=succ->next;
			}
}

8 Risposte

  • Re: Programma sulle liste

    Intanto se il costo è un float anche la funzione deve restituire un float e non un int.

    Il problema però è in

    if (p->disco.costo == max) printf("\n Il disco con il prezzo maggiore è: %s", p->disco.nome);

    che non ha senso dato che sei fuori dal while quindi p è NULL.

    Se vuoi trovare il nome del disco devi farlo all'interno del ciclo in una stringa temporanea in cui lo copi quando assegni il max.
  • Re: Programma sulle liste

    Devo dunque usare una strcpy??
    Scusami non ho capito bene l'ultima frase
  • Re: Programma sulle liste

    Sì ... nel while usa una variabile stringa maxnome e la strcpy per copiare il nome quando copi il max. E fuori dal while la printf di maxnome.

    Una alternativa sarebbe quella di usare un puntatore alla struttura maxp e segnare non i dati ma il puntatore in modo da poterlo utilizzare fuori dal ciclo
  • Re: Programma sulle liste

    Se proprio vogliamo essere puntigliosi, dovresti ricaricare il puntatore e scorrere la lista una seconda volta per stampare tutte le occorrenze che hanno valore massimo
  • Re: Programma sulle liste

    Ho sbagliato non riesco a capire come fare
    
    float max=INT_MIN;
    	char maxnome[25];
    	while(p!=NULL) {
    			if(p->disco.costo > max) max=p->disco.costo;
    			p=p->next;
    			strcpy(maxnome,p->disco.nome);
    			}
    	printf("\n Il massimo è: %f\n", max);
    	printf("\n Il disco con il prezzo maggiore è: %s",maxnome);	
    
    	return max;
  • Re: Programma sulle liste

    Weierstrass ha scritto:


    Se proprio vogliamo essere puntigliosi, dovresti ricaricare il puntatore e scorrere la lista una seconda volta per stampare tutte le occorrenze che hanno valore massimo
    È come faccio? mi sto confondendo tantissimo
  • Re: Programma sulle liste

    Ci sono riuscita, grazie mille!!!!
  • Re: Programma sulle liste

    Ci sono riuscita, grazie mille!!!!
Devi accedere o registrarti per scrivere nel forum
8 risposte