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

    [C]Puntatori a stringhe e strutture

    ciao
    scusate il titolo, ma non sapevo cosa mettere
    ho un problema con il seguente codice: le stringhe memorizzate nella lista
    vengono troncate, e non riesco a capirne il motivo (ho provato a riallocare
    la memoria per le stringhe, ad usare strcpy, memcpy, strncpy, ma senza
    risultati degni di nota )

    ogni aiuto è bene accetto

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct _OneFile_OneRow OneFileOneRow;
    struct _OneFile_OneRow
    {
       char				*artist;
       char				*title;
       char				*path;
       struct _OneFile_OneRow 	*next_file;
    };
    
    void 		playlist_parse(char *playlist_path);
    
    int 		 n_files;
    int		 c_tot;
    char		*playlist_path;
    OneFileOneRow	*ofor;
    OneFileOneRow	*nxt;
    
    int main(int argc, char ** argv)
    {
    	extern int 		 n_files;
    	extern OneFileOneRow 	*ofor;
    	int i;
    	
    	playlist_parse(argv[1]);
    	printf("\n\n%s\n%s\n%s\n\n",
    			"#################################",
    			"# N°   ARTIST    TITLE    PATH  #",
    			"#################################");
    	/* we read the list */
    	for ( i = 0; i < n_files; ++i) 
    	{
    		
    		if (i < 10)
    			putchar(' ');
    		/* 
    		 * as you can see, the strings stored in the various
    		 * artist, title and path have been truncated
    		 */
    		printf("[%d]   %s   %s   %s\n", i,
    				ofor->artist , ofor->title ,ofor->path);
    		ofor = ofor->next_file;
    	}
    
    	return 0;
    }
    
    
    void playlist_parse(char *path_to_list)
    {
    	/* 
    	 * The playlist format is something like:
    	 * 	
    	 * 	ARTIST*TITLE@PATH<newline>
    	 * 	ARTIST*TITLE2@PATH2<newline>
    	 * 	etc...
    	 * 	
    	 * (just here, not in the real program) 
    	 */
    	FILE	*list;
    	char 	*buffer;
    	char 	c;
    	int 	n_c = 0;  
    	
    	playlist_path 	= path_to_list;
    	list 		= fopen(playlist_path, "r");
    	
    	/* 
    	 * we will not test if mem has been properly allocated
    	 * just because this is not the full program
    	 */	
    	ofor 		= calloc(1, sizeof (OneFileOneRow));
            buffer 		= calloc(1, sizeof (char *));
    	nxt  		= ofor;	
    	
    	for (c_tot = 0; (c = getc(list)) != EOF ; ++c_tot)
    	{      
    	       /* 
    	 	* the various printf() functions show the string stored 
    	 	* in buffer is correct
    	 	*/
    		if (c == '\n') 
    		{			
    			*(buffer + n_c) = '\0';
    			if (n_files < 10)
    				putchar(' ');
    			printf("[%d]nxt.PATH    %s\n", n_files, buffer);
    			nxt->path 	= buffer;
    			buffer 		= calloc(1, sizeof (char *));		
    			nxt->next_file 	= calloc(1, sizeof (OneFileOneRow));
    			nxt 		= nxt->next_file;
    			n_c 		= 0;
    			++n_files;
    		}		
    		else if (c == '*') 
    		{
    			*(buffer + n_c) = '\0';
    			if (n_files < 10)
    				putchar(' ');
    			printf("[%d]nxt.ARTIST  %s\n", n_files, buffer);
    			nxt->artist 	= buffer;
    			buffer 		= calloc(1, sizeof (char *));
    			n_c 		= 0;
    		}
    		else if (c == '@') 
    		{
    			*(buffer + n_c) = '\0';
    			if (n_files < 10)
    				putchar(' ');
    			printf("[%d]nxt.TITLE   %s\n", n_files, buffer);
    			nxt->title 	= buffer;
    			buffer 		= calloc(1, sizeof (char *));
    			n_c	 	= 0;
    		}
    		else
    		{
    			*(buffer + n_c) = c; 
    			++n_c;		     
    		}
    	}
    	
    	nxt = NULL;
    	free(buffer);
    	fclose(list);
    	return;
    }
    Grazie in anticipo a tutti

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2005
    Messaggi
    746
    un esempio di lista può essere:

    Richard Wagner*Die Walküre@/percorso/qualsiasi
    Mary Popppins*Supercalifragilistichespiralidoso@/dev/null!

    NOTA: i newline (eccetto l'ultimo) sono importanti

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    E' completamente sbagliata la gestione di

    buffer

    Dato che questo e' un puntatore a char, che presumo ti serva per memorizzare i vari elementi che leggi dal file, non puoi allocarlo cosi' (in neretto l'errore grave)

    buffer = calloc(1, sizeof (char * ));

    perche' non faresti altro che allocare solamente lo spazio per un puntatore (4 byte) e tutto il resto della stringa letta da file sarebbe scritta chissa' dove (sporcando la memoria e provocando un segmentation fault ...).

    L'allocazione del buffer deve essere fatta per un numero congruo di caratteri, ovvero

    buffer = (char *)calloc(80, sizeof (char));

    in modo che non possa essere comunque superata dalla lunghezza della singola linea del file.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2005
    Messaggi
    746
    ora va , grazie infinite

    però mi chiedo:
    • ° perchè i vari printf("[...%s\n", buffer) mostravano le stringhe corrette?
      ° la memoria allocata per "buffer" viene liberata tutta da free(buffer), vero?
      ° un assegnamento di questo tipo

      codice:
      nxt->artist = buffer;
      non è concettualmente errato ?
      cioè, non è che nxt->artist punta a buffer , ma il valore memorizzato in quest'ultimo viene cambiato ?


    scusa la mole non indifferente di domande

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da U-bahn
    scusa la mole non indifferente di domande
    No problem ... un forum e' fatto per le domande.

    1) la funzione printf non controlla che i dati del buffer da visualizzare siano stati allocati correttamente. Essa lavora a partire dall'indirizzo iniziale fino a quando non trova uno zero binario '\0'. L'unico errore puo' essere rilevato se l'indirizzo del dato trattato non e' appartenente al processo attuale (e' il sistema operativo su segnalazione della CPU che interviene in questo caso ...). Ma, nella maggior parte delle volte, anche se il buffer non e' allocato correttamente, in memoria esistono altre variabili facenti parte del processo corrente su sui la printf "sborda" ...

    2) la free libera tutta la memoria allocata ma ... attenzione al punto 3

    3) l'assegnazione e' corretta. In pratica allochi dinamicamente un buffer e in seguito assegni il puntatore all'area allocata al puntatore contenuto nella struttura.
    Ma a questo punto il puntatore a buffer non va passato alla free perche', altrimenti libereresti l'area per i dati di artist che ti serve ancora. Al contrario, quando devi liberare la memoria, devi fare la free di nxt->artist e di tutti le altre aree di memoria allocate.

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2005
    Messaggi
    746
    ho capito
    sei stato chiarissimo, grazie


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 © 2025 vBulletin Solutions, Inc. All rights reserved.