PDA

Visualizza la versione completa : [C] Problema con array di Liste


gaten
14-03-2012, 20:36
Ragazzi questo codice viene compilato correttamente(stò usando Dev C++ 4.9.9.2) però quando vado a scegliere l'ozione 5 del menu, cioè "Crea array di liste", inserisco il numero di liste che voglio creare, però dopo non mi permette di inserire i valori dentro cioè mi stampa a video subito:
"**************Vuoi continuare ad inserire parole nella lista?(S/N)", e come se on leggesse l'fgets che c'è in mezzo.

E' molto più semplice se lo eseguite un attimo , verificate subito il problema.

Grazie anticipatamente.

P.S
C'è una funzione che restituisce il numero di liste che contiene l'array Liste?
Si può fare: lenght(Liste) ???




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



#define MAX_LENGHT 30



/* Dichiaro un tipo di dati NODO */
typedef struct nodo
{
char parola[MAX_LENGHT];
struct nodo *link;
} NODO;



/* Prototipi delle functions */
NODO *InsertInLista(NODO *head, char str[]);
NODO *CancellaNodoLista(NODO *head, char elem[]);
NODO *CancIntervParole(NODO *head, int flag, char inf[], char sup[]);
NODO **CreaListe(NODO **Liste, int Num_Liste);
void StampaLista(NODO *head);
void DeallocaLista(NODO *head);
void InserisciDaTastiera(char *stringa, int Max);



/* Entry point */
main()
{
NODO *head;
head=NULL;
char str[MAX_LENGHT];
char inf[MAX_LENGHT];
char sup[MAX_LENGHT];
char elem[MAX_LENGHT];
int choise;
int flag;
int Num_Liste;
int id=0;

// per la fusione dichiaro un array di liste o lista di liste
NODO **Liste=NULL;



do
{
/* Menu */
printf("Gestisci lista, scegli una delle seguenti opzioni:\n");
printf("[1]. Inserisci nella lista\n");
printf("[2]. Stampa la lista\n");
printf("[3]. Dealloca la lista\n");
printf("[4]. Cancella elemento dalla lista\n");
printf("[5]. Crea un array di liste\n");
printf("[6]. Cancella un intervallo di parole\n");

/* Scelgo cosa fare */
choise = _getch();

/* Stampo a video la scelta effettuata */
printf("Scelta numero > %c \n", choise);

switch(choise)
{
// Inserisco un elemento nella lista
case '1':
printf("Inserisci una nuova parola da inserire nella lista:\n");
fgets(str, 30, stdin);
head=InsertInLista(head, str);
break;

// Stampo a video il contenuto della lista
case '2':
printf("Lista:\n");
printf("---------------\n");
StampaLista(head);
break;

// Dealloco la lista
case '3':
DeallocaLista(head);
head=NULL;
break;

// Cancello un nodo dalla lista
case '4':
printf("Inserisci la parola da cancellare:\n");
fgets(elem, 30, stdin);
head = CancellaNodoLista(head, elem);
break;

// Crea array di liste
case '5':
printf("Quante liste vuoi creare? \n");
//Num_Liste = _getch();
scanf("%d", &Num_Liste);
CreaListe(Liste, Num_Liste);
break;

// Cancello un intervallo di parole
case '6':
printf("Inserisci se le parole devono avere lunghezza pari o dispari(1=pari, 2=dispari):\n");
flag = _getch();
printf("Inserisci la stringa che delimita il lim inf. :\n");
fgets(inf, 30, stdin);
printf("Inserisci la stringa che deliminita il lim sup. :\n");
fgets(sup, 30, stdin);
CancIntervParole(head, flag, inf, sup);
break;
};
} while(choise != '3');

system("\npause");
}
/* End Entry point */



/* =============================================
** Function per stampare a video il contenuto
** della lista
** ---------------------------------------------*/
void StampaLista(NODO *head)
{

if (head != NULL)
{
printf("%s \n", head->parola);
StampaLista(head->link);
}
else
return;
}



/* =============================================
** Function per inserire un nuovo nodo nella lista
** ---------------------------------------------*/
NODO *InsertInLista(NODO *head, char str[])
{
NODO *NewNode;
NewNode=(NODO *)malloc(sizeof(NODO));

if (head == NULL || strcmp(head->parola, str) >= 0 )
{
strcpy(NewNode->parola, str);
NewNode->link=head;
head=NewNode;
}
else
{
head->link=InsertInLista(head->link, str);
}

return head;
}



/* =============================================
** Function per deallocare una lista in memoria
** ---------------------------------------------*/
void DeallocaLista(NODO *head)
{
if (head)
{
DeallocaLista(head->link);
free(head);
}
}



/* =============================================
** Function per cancellare un nodo dalla lista
** ---------------------------------------------*/
NODO *CancellaNodoLista(NODO *head, char elem[])
{
NODO *temp;

if (head)
{
// verifico se ho trovato l'elemento da eliminare
if (strcmp(head->parola, elem) == 0)
{
temp=head;
head=head->link;
free(temp);
}
else
{
head->link = CancellaNodoLista(head->link, elem);
}
}
return head;
}



/* =============================================
** Function per cancellare un intervallo di parole
** ---------------------------------------------*/
NODO *CancIntervParole(NODO *head, int flag, char inf[], char sup[])
{
if (head)
{
// devo considerare le stringhe di lunghezza pari
if (flag == 1)
{
// verifico se la lunghezza della stringa è pari
if (strlen(head->parola) % 2 == 0)
{
head->link = CancellaNodoLista(head, head->parola);
}
else
head->link = CancIntervParole(head->link, flag, inf, sup);
}
// devo considerare le stringhe di lunghezza dispari
else
{
// verifico se la lunghezza della stringa è dispari
if (strlen(head->parola) % 2 == 1)
{
head->link = CancellaNodoLista(head, head->parola);
}
else
{
head->link = CancIntervParole(head->link, flag, inf, sup);
}
}
}

return head;
}



/* =============================================
** Function per leggere una stringa di caratteri
** da tastiera
** ---------------------------------------------*/
void InserisciDaTastiera(char *stringa, int Max)
{
int i;

fgets(stringa, Max, stdin);

for ( i=0; stringa[i] < 0 || stringa[i] > 31; i++);
stringa[i]=0;

fflush(stdin);
}



/* =============================================
** Function per creare un array di n liste
** ---------------------------------------------*/
NODO **CreaListe(NODO **Liste, int Num_Liste)
{
int j;
int id=0;
char str[MAX_LENGHT];
char continua;

// Dico prima quanto spazio totale devo allocare
Liste=malloc(Num_Liste*sizeof(NODO));

for (j=0; j<Num_Liste; j++)
{
// Setto tutte le teste delle liste a NULL
Liste[j]=NULL;
}

while (id < Num_Liste)
{
do
{
printf("**************Inserisci una parola nella lista num. %d \n", id);

fgets(str, 30, stdin);

// Richiamo la function per inserire un elemento nella lista
InsertInLista(Liste[id], str);

// Chiedo se continuare ad inserire altri elementi nella lista corrente
printf("**************Vuoi continuare ad inserire parole nella lista?(S/N)\n");

continua=getchar();
}
while(continua == 's');

id++;
}

// Per il debug
for (j=0; j<Num_Liste; j++)
{
printf("# Lista numero > %d \n", j);
StampaLista(Liste[j]);
printf("\n");
}

return Liste;
}

oregon
14-03-2012, 21:05
Hai svuotato il buffer della tastiera dopo la scanf ?

gaten
14-03-2012, 22:30
no, come faccio?

grazie

gaten
14-03-2012, 22:35
Si ho appena modificato mettendo un fflush(stdin) prima dell'fgets, però quando inserisco, dopo non stampa nulla... come mai?

oregon
14-03-2012, 22:35
E' l'argomento più discusso nel forum ... se fai una ricerca trovi tanti thread ...

Comunque, dopo la scanf

while (getchar() != '\n') ;

gaten
14-03-2012, 22:42
oregon, ho risolto questo problema, il problema ora è un altro che quando inserisco le parole, nella lista dopo, dovrei stamparle ma non stampa nulla...

oregon
14-03-2012, 23:35
Cioè? Di quale parte di codice parli?

ramy89
15-03-2012, 11:04
Nella InsertInLista l' istruzione head=NewNode; viene eseguita solo su una variabile di copia, che non è quella originale.

ramy89
15-03-2012, 13:51
NODO *InsertInLista(NODO **head, char str[])
{
NODO *NewNode;
NewNode=(NODO *)malloc(sizeof(NODO));

if (*head == NULL || strcmp((*head)->parola, str) >= 0 )
{
strcpy(NewNode->parola, str);
NewNode->link=*head;
*head=NewNode;
}
else
{
(*head)->link=InsertInLista((*head)->link, str);
}

return *head;
}


E lo stesso vale per tutte le funzioni in cui ha fatto questo errore.
Se tu hai una funzione:



void cambia(void* ptr)
{
ptr=NULL;
}


Il puntatore originale non viene cambiato, perchè il passaggio di parametri in C è per copia.In C++ si può fare per riferimento.
Se tu invece fai:



void cambia(void* ptr) // ptr zona di memoria allocata
{
*((int*)ptr)=5;
}


La variabile puntata da ptr viene cambiata.Ma questo non perchè il parametro puntatore a void passato alla funzione non viene copiato.Viene copiato il parametro, è solo che punta alla stessa area di memoria.

Loading