Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    654

    [C] Lista non funzionante

    Il mio programma deve richiedere l'inserimento dei campi nome, cognome e età, che compongono un record. Devo implementare una lista di record e stamparli su file. Inserisco il codice qui sotto (quello costruito da me), in fondo vi posto la domanda:


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

    typedef struct a{
    char nome[21];
    char cognome[21];
    int eta;
    struct a *next;
    }anag;

    /*richiamo alla funzione che memorizza la lista dei record anagrafici*/
    anag *anagrafia();

    /*richiamo alla funzione di stampa dei record su file*/
    void stampa(FILE *f, anag *lista);


    int main(int arg, char* args[])
    {
    char s;
    anag *head; //primo elemento della lista
    anag *p;
    FILE *destinazione;


    if(arg!=2)
    printf("Errore di esecuzione: inseriti parametri inesatti"
    " al lancio del programma. Dev'essere della forma (il file"
    " di destinazione deve gia' esistere):\n"
    "fileDaEseguire fileDiDestinazione.\n");

    else{
    printf("Digitare i dati del primo record:\n");
    head = anagrafia();
    p=head;

    do{
    printf("Digitare [s] per introdurre un altro record,"
    " qualunque altro tasto per terminare:\n");
    scanf("%c", &s);
    p->next=anagrafia();
    p=p->next; //p punta alla fine della lista
    }while(s=='s'||s=='S');


    destinazione = fopen(args[1], "w");
    stampa(destinazione, head);
    printf("Operazione giunta a buon fine. I record sono stati"
    " stampati sul file %s.", args[1]);
    fclose(destinazione);
    }
    getch();
    }

    /*Definizione della funzione che permette di memorizzare i campi anagrafici
    per la creazione della lista.*/

    anag *anagrafia(){

    /*Creazione del nodo, ovvero un puntatore contenente i campi della
    struttura creata.*/
    anag *nodo=(anag *)malloc(sizeof(anag));

    printf("Inserire il nome (massimo 20 caratteri):\n");
    scanf("%s", nodo->nome);
    printf("Inserire il cognome (massimo 20 caratteri):\n");
    scanf("%s", nodo->cognome);
    printf("Inserire l'eta':\n");
    scanf("%d", &(nodo->eta));

    /*Pone il campo next della struttura (anch'esso una struttura uguale
    all'intera struttura creata) vuota, poichè la funzione descrive solo un
    record e non è fatta per creare un altro record. L'aggiunta di un
    eventuale nuovo record è fatto nel main.*/
    nodo->next=NULL;

    return nodo;
    }


    void stampa(FILE *f, anag *lista) {

    anag *p; /*puntatore ad un elemento della lista*/

    p = lista;

    fprintf(f, "Elenco dei record memorizzati \n");
    fprintf(f, "*******************\n");

    /*scorrimento della lista per la stampa degli elementi fino a che p
    punta a NULL, ovvero in fondo alla lista*/
    while (p != NULL) {
    fprintf(f,"nome = %s\n", p->nome);
    fprintf(f,"cognome = %s\n", p->cognome);
    fprintf(f,"eta' = %d\n", p->eta);
    fprintf(f, "*******************\n");

    p = p->next;
    }

    return;
    }



    Eseguendolo mi permette di scrivere il record una volta, quindi appare la richiesta se desidero inserire di nuovo il record, ma non mi permette di scegliere: semplicemente mi obbliga a scrivere un secondo record. Dopodichè non mi domanda più se desidero inserire il record e termina.
    Secondo me il problema sta nel punto che ho segnato di rosso.
    Qualcuno ha un'idea?

    Grazie

  2. #2
    Utente di HTML.it L'avatar di DydBoy
    Registrato dal
    Jul 2005
    Messaggi
    165
    Anziche usare la scanf per prendere il carattere usa la getch();

    Credo che il sistema bufferizzi , quando premi s, la "s" come singolo carattere e il "\n" come carattere inserito successivamente.
    Ecco perchè ti forza direttamente ad andare avanti, è come se avessi inserito due caratteri anzichè uno.
    Con la getch() eviti tutto questo.

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    654
    Ho fatto un passo avanti
    Con getch, da te consigliato, adesso mi permette di leggere da tastiera alla richiesta. Però rimane il problema che mi consente di ripetere il ciclo solo una volta.
    Devo fare in modo che possa ripeterlo finchè l'utente non digiti una lettera diversa da "s".

  4. #4
    Utente di HTML.it L'avatar di GabbOne
    Registrato dal
    Mar 2006
    Messaggi
    577
    mica ai provato a fare qualche prinf() dopo il ciclo do-while (il ciclo mi sembra corretto :master: ) ?
    Se non vedi l'output desiderato forse l'errore si trova dentro qualche funzione

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2005
    Messaggi
    746
    ho cambiato qualcosina (più per mio divertimento che altro )...
    ho lasciato il limite dei 20 caratteri per non modificare eccessivamente il codice
    comunque...ora va
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct a anag;
    struct a
    {
    	char 		nome[21];
    	char 		cognome[21];
    	char 		eta[21];
    	struct a 	*next;
    };
    
    anag 	*anagrafia(void);
    void 	stampa(FILE *f, anag *lista);
    
    int main(int argc, char **argv)
    {
    	int	i;
    	char 	s;	 
    	anag 	*p;
    	anag 	*head;
    	FILE 	*dest_file;	
    	
    	if (argc != 2) {
    		fprintf(stderr, "\n%s%s%s%s%s%s\n",
    				"Errore di esecuzione: inseriti parametri ",
    				"inesatti al lancio del programma.\nUtilizzo",
    				"(il file di destinazione deve ", 
    				"gia' esistere):\n\n", 
    				argv[0], " <fileDiDestinazione>\n");
    		return 1;
    	} 
    	else {		
    		if ((dest_file = fopen(argv[1], "w")) == NULL) {
    			return 1;
    		}
    		printf("\nDigitare i dati del primo record:\n");
    		head 	  = anagrafia();
    		p 	  = head;
    	}	
    	
    	
    	
    	for (i = 1; i == 1; ) {
    		printf("%s%s%s",
    				"Digitare [s] per introdurre ",
    				"un altro record, qualunque ",
    				"altro tasto per terminare:\n");
           /* 
            * Il problema era verosimilmente :) "qui" 
            * (riportando questo codice al tuo)
            * ...ora il primo getchar() assegna il carattere ad s, 
            * il secondo prende '\n' 
            */
     		s = getchar();
                    getchar();
    		switch (s) {
    			case 's':
    			case 'S':
    				p->next = anagrafia();
    				p       = p->next;
    				break;
    			default:
    				i = 0;
    				break;
    		}
    	}
    	
    	
    	stampa(dest_file, head);	
    	fclose(dest_file);
    	printf("Operazione giunta a buon fine. I record sono stati %s\"%s\".", 
    			"stampati sul file ", argv[1]);
    	
    	getchar();
    	return 0;
    }
    
    
    anag *anagrafia()
    {		
    	anag 	*nodo;
    	char	*buf;
    	char 	c;
    	int  	i;
    	int  	chk;		
    	
    	chk 	= i = 0;
    	nodo	= malloc(sizeof (anag));
    	buf	= malloc(sizeof (char *));		
    	
    	printf("Inserire il nome (massimo 20 caratteri):\n");
    	while ((c = getchar())) {		
    		if (c != '\n' && i < 20){
    			*(buf + i) = c;			
    		}
    		if (c == '\n') {
    			*(buf + i) = '\0';
                            i          =  -1 ;
    			chk       +=   1 ;
    						
    			if (chk == 1) {
    				strcpy(nodo->nome, buf);
    				printf("Inserire il cognome %s:\n", 
    						"(massimo 20 caratteri)");
    			}
    			else if (chk == 2) {
    				strcpy(nodo->cognome, buf);
    				printf("Inserire l'eta' %s:\n",
    						"(massimo 20 caratteri)"); 
    			}
    			else if (chk == 3) {
    				strcpy(nodo->eta, buf);
    				nodo->next = NULL;
    				break;
    			}
    			buf = realloc(NULL, sizeof (char *));
    		}		
    		++i;
    	}
    	return nodo;
    }
    
    
    
    void stampa(FILE *f, anag *lista) 
    {
    	anag *p;
    	
    	p = lista;
    	
    	fprintf(f, "Elenco dei record memorizzati \n");
    	fprintf(f, "*******************\n");	
    	while (p != NULL) {
    		fprintf(f,"nome = %s\n", p->nome);
    		fprintf(f,"cognome = %s\n", p->cognome);
    		fprintf(f,"eta' = %s\n", p->eta);
    		fprintf(f, "*******************\n");
    		p = p->next;
    	}
    
    return;
    }

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2005
    Messaggi
    654
    Grazie mille, sono riuscito a farlo andare
    Mi sono accorto che avevo modificato una variabile durante la sistemazione...
    Ora tutto funziona!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.