Oppure

Loading
Questo topic e' stato chiuso dal moderatore.
14/02/17 17:42
Djot
Salve a tutti , premetto di essere un novizio della programmazione in generale , volevo chiedervi un aiuto riguardo un esercizio da me svolto ;
L'esercizio consisteva nel generare strutture dati necessarie a rappresentare una lista di escursioni(composta da luogo di partenza ,
luogo di arrivo , distanza percorsa e tempo impiegato) e definire una funzione che dato un intero i restituisce luogo di partenza e di arrivo dellÂ’escursione in posizione i-esima.
Il mio codice è questo :

#include <iostream>
#include <malloc.h>
using namespace std;
int const x = 200;

struct Escursione{
	char luogoPartenza[x];
	char luogoArrivo[x];
	int distanza;
	int tempo;
};
Escursione e1 , e2 , e3;
struct lista{
	Escursione val;
	lista *next;
};
void creaLista(lista , Escursione){
	Escursione e1 , e2 , e3;
	typedef lista* ptr_lista;
	ptr_lista primo;
	primo->val=e1;
	ptr_lista secondo;
	primo->next=secondo;
	secondo->val=e2;
	ptr_lista terzo;
	secondo->next=terzo;
	terzo->val=e3;
	ptr_lista coda;
	terzo->next=coda;
	coda->val=NULL;
}
void leggi(lista , Escursione){
	lista *q;
	q=primo;
	while(q!=NULL){
		cout << q->val;
		q=q->next;
	}
}
int main(lista,Escursione){
	int n , i;
	for(cin >> i; i<=n ; i++){
		if(i==e1.distanza)
			cout << e1.luogoArrivo << e1.luogoPartenza;
		else if(i==e2.distanza)
			cout << e2.luogoArrivo << e2.luogoPartenza;
		else if(i==e3.distanza)
			cout << e2.luogoArrivo << e3.luogoPartenza;
		else
			cout << "Errore";
       }
	return 0;
}


Se potete elencare eventuali e probabili errori ve ne sarei grato.
Grazie mille a tutti
Ultima modifica effettuata da Djot 14/02/17 18:50
aaa
14/02/17 23:58
lumo
Da dove stai imparando il C++? Ci sono moltissimi errori di base, sarebbe troppo lungo spiegarli tutti, magari possiamo aiutarti a trovare risorse migliori.
aaa
15/02/17 7:31
torn24
Hai usato due struct "strutture dati record" e va bene, ma sbagli e non hai creato nessuna lista.
Una lista è una struttura dati dinamica, quindi prevede puntatori e allocazione dinamica della memoria.
I passi sono

1) Si crea un nodo puntatore Lista, e si alloca memoria
2) Si inseriscono i dati nei vari campi del nodo
3) Si crea una funzione inserisci nodo, che crea un nuovo nodo, inserisce valori nei campi, e concatena il nuovo nodo alla Lista.

Sbagli il passaggio di parametri alle funzioni "da qui mi domando se non è troppo presto che tu ti cimenti con le liste, forse dovresti fare un ripasso di concetti base", comunque per passare un argomento a una funzione,
occorre specificane nella funzione TIPO e parametro Esempio void creaLista(lista l , Escursione e), vedi aggiunta di "l" e "e".


In pratica usi Escursione e1 , e2 , e3; che sono semplici struct, ma non crei nessuna lista.
Parere personale.
Per affrontare l'esercizio dovresti ripassare puntatori a struct e studiare esempi di lista.
aaa
15/02/17 21:10
AldoBaldo
Viste le premesse, non sarebbe consigliabile tentare un'implementazione per mezzo di un array statico di dimensioni fisse per predisporre alcuni elementi base del programma e dopo modificare le cose per basarle effettivamente sull'impiego di una lista concatenata con allocazione dinamica dei nuovi record? Spero d'essere riuscito a spiegarmi.
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
15/02/17 23:33
AldoBaldo
Tipo...

File escursione.h:

#ifndef ESCURSIONE_H
#define ESCURSIONE_H

#define QMAXESC  64 // la quantita' massima di escursioni
#define LMAXSTR 255 // la lunghezza massima delle stringhe

typedef struct ESCURSIONE {
    char lp[LMAXSTR+1]; // luogo di partenza
    char la[LMAXSTR+1]; // luogo di arrivo
    unsigned int d;     // la distanza (in metri)
    unsigned int t;     // il tempo richiesto (in minuti)
} ESCURSIONE;

ESCURSIONE *CreaEscursione( void );
void DistruggiEscursione( ESCURSIONE **e );

int AggiungiEscursione( ESCURSIONE **esc, unsigned int *qEsc );
void EliminaEscursione( ESCURSIONE **esc, unsigned int *qEsc );

void ImpostaEscursione( ESCURSIONE *e,
    const char *partenza, const char *arrivo,
    double km, unsigned int h, unsigned int m );
void ImpostaPartenzaEscursione( ESCURSIONE *e, const char *partenza );
void ImpostaArrivoEscursione( ESCURSIONE *e, const char *arrivo );
void ImpostaTempoEscursione( ESCURSIONE *e, unsigned int h, unsigned int m );
void ImpostaDistanzaEscursione( ESCURSIONE *e, double km );

void StampaEscursione( ESCURSIONE *e );

#endif // ESCURSIONE_H


File escursione.c

#include "escursione.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/*==============================================================================
Alloca dinamicamente una struttura di tipo ESCURSIONE impostata interamente su
zeri e ne restituisce il puntatore. In caso di fallimento restituisce NULL.
==============================================================================*/

ESCURSIONE *CreaEscursione( void ) {
    return calloc( 1, sizeof(ESCURSIONE) );
}

/*==============================================================================
Distrugge una struttura di tipo ESCURSIONE precedentemente allocata in memoria
dinamica e ne imposta il puntatore su NULL.
==============================================================================*/

void DistruggiEscursione( ESCURSIONE **e ) {
    if( e ) { free( *e ); *e = NULL; }
}

/*==============================================================================
Aggiunge in cima all'array esc il puntatore ad una struttura di tipo ESCURSIONE
appositamente allocata in memoria dinamica e aggiorna il contatore dei puntatori
contenuti nell'array. Se l'aggiunta va a buon fine restituisce 0; in caso
contrario restituisce un codice di errore.
==============================================================================*/

int AggiungiEscursione( ESCURSIONE **esc, unsigned int *qEsc ) {
    if( esc != NULL && qEsc != NULL ) {
        if( *qEsc < QMAXESC ) {
            esc[*qEsc] = CreaEscursione();
            if( esc[*qEsc] != NULL ) {
                ++(*qEsc);
                return 0;       // tutto bene!
            } else return 3;    // allocazione fallita
        } else return 2;        // array saturo
    } else return 1;            // parametro non valido
}

/*==============================================================================
Elimina dalla cima dell'array esc il puntatore ad una struttura di tipo
ESCURSIONE appositamente allocata in memoria dinamica e aggiorna il contatore
dei puntatori contenuti nell'array.
==============================================================================*/

void EliminaEscursione( ESCURSIONE **esc, unsigned int *qEsc ) {
    if( *qEsc > 0 ) DistruggiEscursione( &esc[--*qEsc] );
}

/*==============================================================================
Imposta tutti i campi della struttura di tipo ESCURSIONE coerentemente coi
parametri passati.
==============================================================================*/

void ImpostaEscursione( ESCURSIONE *e,
    const char *partenza, const char *arrivo,
    double km, unsigned int h, unsigned int m ) {
    ImpostaPartenzaEscursione( e, partenza );
    ImpostaArrivoEscursione( e, arrivo );
    ImpostaDistanzaEscursione( e, km );
    ImpostaTempoEscursione( e, h, m );
}

/*==============================================================================
Funzione ausiliaria per ImpostaPartenzaEscursione() e ImpostaArrivoEscursione().
==============================================================================*/

void ImpostaStringa( char *dest, const char *orig ) {
    if( dest != NULL && orig != NULL )
        strncpy( dest, orig, LMAXSTR );
    else if( dest != NULL ) *dest = 'Tipo...


File escursione.h:

#ifndef ESCURSIONE_H
#define ESCURSIONE_H

#define QMAXESC  64 // la quantita' massima di escursioni
#define LMAXSTR 255 // la lunghezza massima delle stringhe

typedef struct ESCURSIONE {
    char lp[LMAXSTR+1]; // luogo di partenza
    char la[LMAXSTR+1]; // luogo di arrivo
    unsigned int d;     // la distanza (in metri)
    unsigned int t;     // il tempo richiesto (in minuti)
} ESCURSIONE;

ESCURSIONE *CreaEscursione( void );
void DistruggiEscursione( ESCURSIONE **e );

int AggiungiEscursione( ESCURSIONE **esc, unsigned int *qEsc );
void EliminaEscursione( ESCURSIONE **esc, unsigned int *qEsc );

void ImpostaEscursione( ESCURSIONE *e,
    const char *partenza, const char *arrivo,
    double km, unsigned int h, unsigned int m );
void ImpostaPartenzaEscursione( ESCURSIONE *e, const char *partenza );
void ImpostaArrivoEscursione( ESCURSIONE *e, const char *arrivo );
void ImpostaTempoEscursione( ESCURSIONE *e, unsigned int h, unsigned int m );
void ImpostaDistanzaEscursione( ESCURSIONE *e, double km );

void StampaEscursione( ESCURSIONE *e );

#endif // ESCURSIONE_H


File escursione.c

#include "escursione.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/*==============================================================================
Alloca dinamicamente una struttura di tipo ESCURSIONE impostata interamente su
zeri e ne restituisce il puntatore. In caso di fallimento restituisce NULL.
==============================================================================*/

ESCURSIONE *CreaEscursione( void ) {
    return calloc( 1, sizeof(ESCURSIONE) );
}

/*==============================================================================
Distrugge una struttura di tipo ESCURSIONE precedentemente allocata in memoria
dinamica e ne imposta il puntatore su NULL.
==============================================================================*/

void DistruggiEscursione( ESCURSIONE **e ) {
    if( e ) { free( *e ); *e = NULL; }
}

/*==============================================================================
Aggiunge in cima all'array esc il puntatore ad una struttura di tipo ESCURSIONE
appositamente allocata in memoria dinamica e aggiorna il contatore dei puntatori
contenuti nell'array. Se l'aggiunta va a buon fine restituisce 0; in caso
contrario restituisce un codice di errore.
==============================================================================*/

int AggiungiEscursione( ESCURSIONE **esc, unsigned int *qEsc ) {
    if( esc != NULL && qEsc != NULL ) {
        if( *qEsc < QMAXESC ) {
            esc[*qEsc] = CreaEscursione();
            if( esc[*qEsc] != NULL ) {
                ++(*qEsc);
                return 0;       // tutto bene!
            } else return 3;    // allocazione fallita
        } else return 2;        // array saturo
    } else return 1;            // parametro non valido
}

/*==============================================================================
Elimina dalla cima dell'array esc il puntatore ad una struttura di tipo
ESCURSIONE appositamente allocata in memoria dinamica e aggiorna il contatore
dei puntatori contenuti nell'array.
==============================================================================*/

void EliminaEscursione( ESCURSIONE **esc, unsigned int *qEsc ) {
    if( *qEsc > 0 ) DistruggiEscursione( &esc[--*qEsc] );
}

/*==============================================================================
Imposta tutti i campi della struttura di tipo ESCURSIONE coerentemente coi
parametri passati.
==============================================================================*/

void ImpostaEscursione( ESCURSIONE *e,
    const char *partenza, const char *arrivo,
    double km, unsigned int h, unsigned int m ) {
    ImpostaPartenzaEscursione( e, partenza );
    ImpostaArrivoEscursione( e, arrivo );
    ImpostaDistanzaEscursione( e, km );
    ImpostaTempoEscursione( e, h, m );
}

/*==============================================================================
Funzione ausiliaria per ImpostaPartenzaEscursione() e ImpostaArrivoEscursione().
==============================================================================*/

void ImpostaStringa( char *dest, const char *orig ) {
    if( dest != NULL && orig != NULL )
        strncpy( dest, orig, LMAXSTR );
    else if( dest != NULL ) *dest = '{parsed_message}';
}

/*==============================================================================
Imposta il campo lp (luogo di partenza) della struttura ESCURSIONE, curando che
non venga superato il limite imposto dalle dimensioni dello spazio disponibile.
==============================================================================*/

void ImpostaPartenzaEscursione( ESCURSIONE *e, const char *partenza ) {
    ImpostaStringa( e->lp, partenza );
}

/*==============================================================================
Imposta il campo la (luogo di arrivo) della struttura ESCURSIONE, curando che
non venga superato il limite imposto dalle dimensioni dello spazio disponibile.
==============================================================================*/

void ImpostaArrivoEscursione( ESCURSIONE *e, const char *arrivo ) {
    ImpostaStringa( e->la, arrivo );
}

/*==============================================================================
Imposta il campo t (tempo) della struttura ESCURSIONE, "accorpando" i valori
delle ore e dei minuti.
==============================================================================*/

void ImpostaTempoEscursione( ESCURSIONE *e, unsigned int h, unsigned int m ) {
    if( e != NULL ) e->t = h*60 + m;
}

/*==============================================================================
Imposta il campo d (distanza) della struttura ESCURSIONE, trasformando in
metri la quantita' dei km passata. Le quantita' inferiori al metro sono soggette
a un processo d'arrotondamento.
==============================================================================*/

void ImpostaDistanzaEscursione( ESCURSIONE *e, double km ) {
    if( e != NULL ) {
        if( km < 0.0 ) km = -km;
        e->d = round( km*1000.0 );
    }
}

/*==============================================================================
Visualizza in console il contenuto della struttura ESCURSIONE.
==============================================================================*/

void StampaEscursione( ESCURSIONE *e ) {
    if( e != NULL ) {
        unsigned int ore = e->t/60;
        unsigned int min = e->t%60;
        const char ps1[4] = "ea";
        const char ps2[4] = "io";
        printf( "Partenza: %s\n", e->lp );
        printf( "Arrivo:   %s\n", e->la );
        printf( "Distanza: %.2lf km\n", ((double)e->d)/1000.0 );
        printf( "Tempo:    %u or%c", ore, ps1[ore==1] );
        if( min ) printf( " e %u minut%c", min, ps2[min==1] );
        printf( "\n" );
    }
    else {
        printf( "Escursione non valida\n" );
    }
}


Il file escursione.c è in effetti un po' lunghetto, però "isola" alcuni procedimenti in un file "a parte", cosicché uno possa poi pensare al resto delle operazioni con un po' più leggerezza. Ad esempio...

File main.c:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "escursione.h"

int main() {
    ESCURSIONE *esc[QMAXESC]; // array di puntatori a strutture ESCURSIONE
    unsigned int i, qEsc = 0; // qEsc = quantita' di escursioni
    int errore = 0; // zero: nessun errore

    memset( esc, 0, sizeof(ESCURSIONE*)*QMAXESC );

    for( i=0; i<3 && !errore; ++i )
        errore = AggiungiEscursione( esc, &qEsc );

    if( !errore ) {
        ImpostaEscursione( esc[0], "Palermo", "Trento", 1632, 1, 15 );
        ImpostaEscursione( esc[1], "Olbia", "Vieste", 600.5, 6, 45 );
        ImpostaEscursione( esc[2], "Loano", "Pietra Ligure", 0.5, 0, 5 );

        for( i=0; i<qEsc; ++i ) {
            StampaEscursione( esc[i] );
            printf( "\n" );
        }

        while( qEsc != 0 )
            EliminaEscursione( esc, &qEsc );
    }

    return 0;
}
'; } /*============================================================================== Imposta il campo lp (luogo di partenza) della struttura ESCURSIONE, curando che non venga superato il limite imposto dalle dimensioni dello spazio disponibile. ==============================================================================*/ void ImpostaPartenzaEscursione( ESCURSIONE *e, const char *partenza ) { ImpostaStringa( e->lp, partenza ); } /*============================================================================== Imposta il campo la (luogo di arrivo) della struttura ESCURSIONE, curando che non venga superato il limite imposto dalle dimensioni dello spazio disponibile. ==============================================================================*/ void ImpostaArrivoEscursione( ESCURSIONE *e, const char *arrivo ) { ImpostaStringa( e->la, arrivo ); } /*============================================================================== Imposta il campo t (tempo) della struttura ESCURSIONE, "accorpando" i valori delle ore e dei minuti. ==============================================================================*/ void ImpostaTempoEscursione( ESCURSIONE *e, unsigned int h, unsigned int m ) { if( e != NULL ) e->t = h*60 + m; } /*============================================================================== Imposta il campo d (distanza) della struttura ESCURSIONE, trasformando in metri la quantita' dei km passata. Le quantita' inferiori al metro sono soggette a un processo d'arrotondamento. ==============================================================================*/ void ImpostaDistanzaEscursione( ESCURSIONE *e, double km ) { if( e != NULL ) { if( km < 0.0 ) km = -km; e->d = round( km*1000.0 ); } } /*============================================================================== Visualizza in console il contenuto della struttura ESCURSIONE. ==============================================================================*/ void StampaEscursione( ESCURSIONE *e ) { if( e != NULL ) { unsigned int ore = e->t/60; unsigned int min = e->t%60; const char ps1[4] = "ea"; const char ps2[4] = "io"; printf( "Partenza: %s\n", e->lp ); printf( "Arrivo: %s\n", e->la ); printf( "Distanza: %.2lf km\n", ((double)e->d)/1000.0 ); printf( "Tempo: %u or%c", ore, ps1[ore==1] ); if( min ) printf( " e %u minut%c", min, ps2[min==1] ); printf( "\n" ); } else { printf( "Escursione non valida\n" ); } }


Il file escursione.c è in effetti un po' lunghetto, però "isola" alcuni procedimenti in un file "a parte", cosicché uno possa poi pensare al resto delle operazioni con un po' più leggerezza. Ad esempio...

File main.c:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "escursione.h"

int main() {
    ESCURSIONE *esc[QMAXESC]; // array di puntatori a strutture ESCURSIONE
    unsigned int i, qEsc = 0; // qEsc = quantita' di escursioni
    int errore = 0; // zero: nessun errore

    memset( esc, 0, sizeof(ESCURSIONE*)*QMAXESC );

    for( i=0; i<3 && !errore; ++i )
        errore = AggiungiEscursione( esc, &qEsc );

    if( !errore ) {
        ImpostaEscursione( esc[0], "Palermo", "Trento", 1632, 1, 15 );
        ImpostaEscursione( esc[1], "Olbia", "Vieste", 600.5, 6, 45 );
        ImpostaEscursione( esc[2], "Loano", "Pietra Ligure", 0.5, 0, 5 );

        for( i=0; i<qEsc; ++i ) {
            StampaEscursione( esc[i] );
            printf( "\n" );
        }

        while( qEsc != 0 )
            EliminaEscursione( esc, &qEsc );
    }

    return 0;
}
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
16/02/17 14:33
Djot
Grazie mille a tutti per l'attenzione , ho trovato molto utili i vostri consigli , comunque ho provato a riscrivere il codice in questo formato :
#include <iostream>
using namespace std;
char const lenght = 20;

struct Escursione{
	char luogoPartenza[lenght];
	char luogoArrivo[lenght];
	int distanza;
	int tempo;
}e;

struct NodoLista{
	Escursione val;
	NodoLista *next;
}l;

struct NodoLista *crea_lista(){
	typedef NodoLista* ptr_lista;
	ptr_lista head , p;
	int i , n;
	cin >> n;
	if(n==0)
		head = NULL;
	else{
		cin >> head->val.luogoPartenza >> head->val.luogoArrivo >> head->val.distanza >> head->val.tempo;
		p = head->next;
	for(i=0;i<n;i++){
		p=p->next;
		cin >> p->val.luogoPartenza >> p->val.luogoArrivo >> p->val.distanza >> p->val.tempo;;
	}
}
	p->next = NULL;
	return (head);
}

void stampa_lista(struct NodoLista *p , struct NodoLista *head){
	while(head!=NULL)
		cout << head->val.luogoPartenza << head->val.luogoArrivo << head->val.distanza << head->val.tempo;;
	head = head->next;
}

void ricerca_lista(struct NodoLista *p , struct NodoLista *head){
	int i;
	cin >> i;
	while(head->val.distanza!=i){
		head=head->next;
		cout << head->val.distanza;
	}
}
int main(){
	struct NodoLista crea_lista();
	void stampa_lista(struct NodoLista *p , struct NodoLista *head);
	void ricerca_lista(struct NodoLista *p , struct NodoLista *head);
	return 0;
}


Potete darmi una correzione anche di questo?
Grazie mille per l'attenzione.
aaa
16/02/17 16:58
TheDarkJuster
Il tuo ultimo codice non ha molto senso... Non alloca memoria... La usa senza averne il permesso. Se anche si compilasse (hai provato?) terminerebbe in malomodo con un segmentation fault. Inoltre non riesco bene a capire il senso del crea_lista.
aaa
16/02/17 17:15
Djot
Con crea_lista avevo intenzione di definire la lista delle escursioni , per allocazione di memoria intendi la keyword malloc? Non capisco per quale motivo ma il compilatore segna errore ogni volta che provo ad introdurla , nonostante abbia provato varie librerie
aaa