PDA

Visualizza la versione completa : [C] Scorrimento di una lista con aggiornamento di variabili globali


alemutasa
05-08-2015, 16:20
Salve a tutti!

Sto battagliando con una porzione di programma che non riesco a sconfiggere.

In pratica, devo costruire una lista nella quale devo inserire dei dati. Devo, poi, cercare i dati min/max su tale lista per poi salvarli in variabili globali. Il problema è che il codice che ho pensato non funziona e non capisco minimamente il perché. Gli errori sono, nello specifico:
1 - Nella funzione di scorrimento della lista, quando cerco di fare il confronto con node->data e biggestNode->data;
2 - nel file che apro col puntatore info, che non stampa nulla anche quando modifico lo scorrimento della lista.

Ecco il programma:

Dichiarazione dell'elemento della lista


///Dichiaro e definisco il tipo Node
typedef struct Node Node;
struct Node{
int data;
Node *prev;
Node *next;
};


Funzione di scorrimento della lista


///Definizione di funzione di cerca del nodo col dato più grande
void findBiggestNode(Node* node, FILE *infoFile){
///Alloco memoria per la variabile globale
biggestNode = malloc(sizeof(Node));

///Assegno il minimo al nodo più grande
biggestNode->data = 0;

///Ciclo che scorre la lista. Se l'elemento della lista considerato ha un valore più alto di biggestNode, allora memorizzo
///l'indirizzo dell'elemento della lista in biggestNode
while(node != NULL){
if(node->data > biggestNode->data){
biggestNode = node;
fprintf(infoFile, "Trovato nuovo valore massimo = %d\n\n", node->data);
}
///Aggiorno la lista
node = node->next;
}
}


Costruzione della lista


///Funzione di costruzione della lista
Node *addNode(Node *oldNode){
///Dichiaro l'elemento della lista da collegare
Node *newNode;

///Dò memoria al puntatore appena dichiarato
newNode = malloc(sizeof(Node));

///Assegno un numero casuale al campo data
newNode->data = rand() % 10;

///Collego l'ultimo elemento in modo che sia inserito in testa alla lista
oldNode->prev = newNode;
newNode->next = oldNode;
newNode->prev = NULL;

///Valore di ritorno della funzione
return newNode;
}


main() e dichiarazione della variabile globale


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

///Dichiaro una variabile globale che conterrà il nodo col dato più grande
Node *biggestNode;

int main()
{
int i;
Node *node;
FILE *info;

///Dò memoria al puntatore appena dichiarato
node = malloc(sizeof(Node));
if(node == NULL){
printf("Error in memory allocation");
exit(EXIT_FAILURE);
}

///Costruisco la lista, composta da dieci elementi
for(i = 0; i < 10; i++){
node = addNode(node);
printf("%d\n", node->data);
}

info = fopen("c:/users/thisPC/desktop/nodeinfo.txt", "w");
if (info == NULL){
printf("Error while opening file.");
exit(EXIT_FAILURE);
}

///Chiamo la funzione findBiggestNode, che aggiorna la variabile globale biggestNode
findBiggestNode(node, info);

fclose(info);

return 0;
}


Mi aiutate a capire dove sbaglio?

torn24
07-08-2015, 07:17
Ho provato il programma, a parte che all'ultimo nodo della lista risulta data=non assegnato, sembra fuzionare....



Il percorso file in fopen() è sbagliato, prova a correggerlo e vedi se funziona


fopen("c:/users/thisPC/desktop/nodeinfo.txt", "w");


fopen("c:\\users\\thisPC\\desktop\\nodeinfo.txt", "w");

alemutasa
07-08-2015, 09:40
Ho provato il programma, a parte che all'ultimo nodo della lista risulta data=non assegnato, sembra fuzionare....



Il percorso file in fopen() è sbagliato, prova a correggerlo e vedi se funziona


fopen("c:/users/thisPC/desktop/nodeinfo.txt","w");


fopen("c:\\users\\thisPC\\desktop\\nodeinfo.txt","w");

Ciao, grazie mille della risposta! Dunque, il percorso in fopen è corretto (in Windows, proprio per non confondere la navigazione tra cartelle con il primo carattere di ogni sequenza di escape, si usa il carattere /) e comunque, se il file non si potesse aprire col codice che ho scritto, me lo direbbe perché gli ho messo il solito controllo
if(pntr == NULL) eccetera eccetera. Per quanto riguarda il dato mancante sì, è proprio quello il problema! Lanciando il debugger mi dice che c'è un errore di segmentation fault proprio mentre faccio l'assegnamento... Suppongo che sia un problema di scope, però non riesco a capire qual è! :dhò: Hai qualche idea?

torn24
07-08-2015, 10:02
Guarda che il programma funziona, e ne sono abbastanza sicuro perché lo compilato e provato :D

Gli errori erano percorso file, funziona sia la mia che la tua sintassi, è probabile che il percorso sia sbagliato, non puoi vedere il messaggio di errore visto che non metti nessuna pausa tra printf() e exit(), e il fatto che il nodo creato nel main, che tramite il tuo codice divverrà l'ultimo nodo della lista, non è inizializzato a zero, e quindi nodo->data ha valore indefinito.


FAMMI UN FAVORE...
controlla il percorso file, che secondo me non è corretto, per provare puoi mettere solo il nome file che ti verrà creato nella cartella progetto...
COMPILA il tuo codice con le correzioni e dimmi se va o no... PERCHE' A ME VA ;)




///Dichiaro e definisco il tipo Node
typedef struct Node Node;
struct Node{
int data;
Node *prev;
Node *next;
};




#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void findBiggestNode(Node* node, FILE *infoFile);
Node *addNode(Node *oldNode);


///Dichiaro una variabile globale che conterrà il nodo col dato più grande
Node *biggestNode;


int main()
{
int i;
Node *node;

FILE *info;



node = malloc(sizeof(Node));

if(node == NULL){
printf("Error in memory allocation");
getchar();// SE NON METTI UNA PAUSA NON VEDRAI MAI IL MESSAGGIO
exit(EXIT_FAILURE);
}
node->data=0; // DEVI INIZIALIZZARE IL NODO A ZERO, QUESTO SARA' L'ULTIMO NODO

for(i = 0; i < 10; i++){
node = addNode(node);
printf("%d\n", node->data);
}


info = fopen("c:\\users\\thisPC\\desktop\\nodeinfo.txt", "w");
if (info == NULL){
printf("Error while opening file.");
getchar();// SE NON METTI UNA PAUSA NON VEDRAI MAI IL MESSAGGIO DI ERRORE
exit(EXIT_FAILURE);
}




findBiggestNode(node, info);


fclose(info);
getchar();// PAUSA

return 0;
}








///Definizione di funzione di cerca del nodo col dato più grande
void findBiggestNode(Node* node, FILE *infoFile){
///Alloco memoria per la variabile globale
biggestNode = malloc(sizeof(Node));


///Assegno il minimo al nodo più grande
biggestNode->data = 0;


///Ciclo che scorre la lista. Se l'elemento della lista considerato ha un valore più alto di biggestNode, allora memorizzo
///l'indirizzo dell'elemento della lista in biggestNode
while(node != NULL){
if(node->data > biggestNode->data){
biggestNode = node;
fprintf(infoFile, "Trovato nuovo valore massimo = %d\n\n", node->data);
}
///Aggiorno la lista
node = node->next;
}
}


///Funzione di costruzione della lista
Node *addNode(Node *oldNode){
///Dichiaro l'elemento della lista da collegare
Node *newNode;


///Dò memoria al puntatore appena dichiarato
newNode = malloc(sizeof(Node));


///Assegno un numero casuale al campo data
newNode->data = rand() % 10;


///Collego l'ultimo elemento in modo che sia inserito in testa alla lista
oldNode->prev = newNode;
newNode->next = oldNode;
newNode->prev = NULL;


///Valore di ritorno della funzione
return newNode;
}

alemutasa
07-08-2015, 11:42
Il programma che hai proposto tu funziona (e ci credo, se a te compila e non crasha lo fa anche con me), ma la questione del percorso file e dell'errore di segmentaion fault non mi è ancora chiara.

La funzione exit() con la macro EXIT_FAILURE mi ha sempre "bloccato" la schermata, e anche stavolta vedo il messaggio d'errore quando metto un path inesistente. Guarda:



printf("Inserire il percorso del file: ");
scanf("%s", s);

fInfo = fopen(s, "w");
if(fInfo == NULL){
printf("Il percorso %s non esiste. Uscita", s);
exit(EXIT_FAILURE);
}


26223

In più, ho sempre usato il carattere "/" invece che "\\" e ha sempre funzionato!

In ogni caso, l'errore che non mi spiego è proprio quello di segmentation fault, e il debugger mi dice che è nelle condizioni di continuo del ciclo while

torn24
07-08-2015, 13:00
Be, non so cosa dirti, a parte un puntatore non inizializzato ė considerato NULL??
Perché il puntatore next, dell'ultimo nodo, quello dichiarato nel main, ė indefinito. Potrebbe essere questo il problema col while.

Loading