Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it L'avatar di braian
    Registrato dal
    Apr 2007
    Messaggi
    35

    [C] errore di i/0 in ritorno da funzione

    Il seguente codice mi va in segmentation fault al momento del ritorno dalla finzione "createf" richiamata nel main.
    Ho fatto il debugger con DDD e mi pare che vada bene tranne che quando dovrebbe ritornare 0 e invecie va in seg fault.
    Qualcuno può aiutarmi?

    codice:
     
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdarg.h>
    #include <time.h>		 //per la gestione del time
    #include <stdio.h>
    
    
    
    int createf(const char *path,const char *mode,char* fmt,...) //funzione con numero di parametri variabile, i primi 2 servono per la fopen, il terzo è una stringa di formato per i parametri variabili. E'un errore nn passare la stringa di formato, al limite passarla vuota per non inserire metadati. Eventuali parametri in più rispetto a quelli specificati nella stringa di formato vengono ignorati.
    {
    	va_list ap;	//il puntatore a argomento 
    	FILE* file; //il file da creare o modificare
    	FILE* filesave=fopen("save.sav","a"); //il file di salvataggio delle associazioni
    	
    	int lung;
    	char str[1];
    	char* stringa;
    	char* sval;
    	float fval;
    	struct tm * t;
    	time_t tx;
    	
    	if ((file=fopen(path, mode))==NULL)
    	{
    		printf("errore1");
    	}
    	fprintf(filesave,"%s,",path);
    	va_start(ap,fmt);
    	while(*fmt!='\0')
    	{
    		if(isalpha(*fmt)!=0)
    		{
    			lung=strcspn(fmt," ");
    			stringa=strncpy(str,fmt,lung);
    			if(fputs(stringa,filesave)==EOF) //scrive il nome del metadato
    			{
    				printf("errore2");//gestione errore in fputs
    			}
    			fmt=fmt+lung; //fmt punta al successivo formato di tipo metadato(%s,%n..)
    			if(isspace(*fmt)==0)
    			{
    				printf("errore3");//trattamento errore, non c'è lo spazio dopo il nome di metadato
    			}
    			fmt++;
    			if(*fmt=='%')
    			{
    				fmt++;
    				switch(*fmt)
    				{
    					case 's':
    						sval=va_arg(ap,char*);
    						fprintf(filesave,"%s,",sval);
    						fmt++;
    						break;
    					case 'n':
    						fval=va_arg(ap,double);
    						fprintf(filesave,"%f,",fval);
    						fmt++;
    						break;
    					case 'd':
    						t=va_arg(ap,struct tm*);
    						tx=mktime(t);
    						if (tx == (time_t) (-1))
          					{
          						printf ("Errore! %ld\n", (long int) tx); //trattamento errore data da rivedere
         					}
        					fprintf(filesave,"%d/%d/%d,",t->tm_mday,t->tm_mon+1,t->tm_year+1900);
        					fmt++;
    						break;
    					default :
    						printf("errore4");//trattamento errore formato sconosciuto
    						break;
    				}
    			}
    			else
    			{
    				printf("errore5");//gestione errore, non c'è % dopo il nome del metadato e lo spazio
    			}
    		
    		}
    		
    	}
    	fprintf(filesave,"\n");
    	
    	return 0;
    	
    }
    
    
    
    int createfwm(const char *path,const char *mode)
    {
    	FILE* file;
    	FILE* filesave=fopen("save.sav","a"); //il file di salvataggio delle associazioni
    	if ((file=(fopen(path, mode)))==((FILE*)NULL))
    	{
    		return EOF; //gestione errore
    	}
    	fprintf(filesave,"%s\n",path);
    	if(fclose(filesave)==EOF)
    	{
    		return EOF; //gestione errore
    	}
    	return 1;
    }
    
    int main()
    {
    	printf("tuttook0\n");
    	struct tm* tempo;
    	tempo->tm_year=150;
    	tempo->tm_mday=15;
    	tempo->tm_mon=5;
    	char car;
    	int a=createfwm("prova.pro","w");
    	int b=createfwm("provi.pri","w");
    	int c=createfwm("prove.pre","w"); 
    	printf("tuttook1");
    	int d=createf("provu.pru","w","proprietario %srevisione %ndata %d","paolo",5,tempo);
    	printf("tuttook2");
    	FILE* fil=fopen("save.sav","r");
    	while((car=fgetc(fil))!=EOF)
    	{
    		if(car=='\0')
    		printf("errore");
    	}
    	printf("tuttook");
    	fclose(fil);
    	return 1;
    }
    L'errore che DDD mi da è:
    Error accessing memory address 0x86f6972: Input/output error

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Ci sono sicuramente due errori gravi (ma potrebbero non essere i soli ...)

    1) nel main, inizializzi gli elementi di tempo ma la struttura non e' stata allocata ... hai solamente il puntatore ...

    2) nella createf, quando esegui la

    stringa=strncpy(str,fmt,lung);

    la variabile lung vale 12 mentre la destinazione della copia (str) e' dichiarata con un solo carattere (char str[1] ... in questo modo la strncpy "sporca" le variabili che stanno vicine alla str e da quel momento i puntatori "sballano" puntando a zone di memoria non lecite ... da cui l'errore ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it L'avatar di braian
    Registrato dal
    Apr 2007
    Messaggi
    35
    Grazie mille

  4. #4
    Utente di HTML.it L'avatar di braian
    Registrato dal
    Apr 2007
    Messaggi
    35
    Con il seguente codice mi resta solo il problema che il puntatore allo struct tm che passo dal main alla mia funzione non viene utilizzato correttamente dalla funzione, in particolare non riesco a salvare su file la data.
    Vedendo il debugger non capisco molto...
    Help...
    Poi resta anche il fatto che nella mia funzione scrivo subito su file senza aspettare la finde della stringa di formato....potrebbero esserci degli errori e a quel punto avrei già scritto su file.
    Che ne pensate? Probabilmente non è un approcio corretto...

    codice:
     
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdarg.h>
    #include <time.h>		 //per la gestione del time
    #include <stdio.h>
    
    
    
    int createf(const char *path,const char *mode,char* fmt,...) //funzione con numero di parametri variabile, i primi 2 servono per la fopen, il terzo è una stringa di formato per i parametri variabili. E'un errore nn passare la stringa di formato, al limite passarla vuota per non inserire metadati. Eventuali parametri in più rispetto a quelli specificati nella stringa di formato vengono ignorati.
    {
    	va_list ap;	//il puntatore a argomento 
    	FILE* file; //il file da creare o modificare
    	FILE* filesave=fopen("save.sav","a"); //il file di salvataggio delle associazioni
    	int close;
    	int lung;
    	char* stringa;
    	char* sval;
    	float fval;
    	struct tm * t;
    	time_t tx;
    
    	int scritti;
    	
    	if ((file=fopen(path, mode))==NULL)
    	{
    		printf("errore1");
    	}
    	scritti=fprintf(filesave,"%s,",path);
    	if (scritti<0)
    	{
    		printf("errore 10");//trattamento errore
    	}
    	va_start(ap,fmt);
    	while(*fmt!='\0')
    	{
    		if(isalpha(*fmt)!=0)
    		{
    			lung=strcspn(fmt," ");
    			char *str=malloc(sizeof(char)*lung+1);
    			stringa=strncpy(str,fmt,lung);
    			stringa[lung]='\0';
    			if(fputs(stringa,filesave)==EOF) //scrive il nome del metadato
    			{
    				printf("errore2");//gestione errore in fputs
    			}
    			fputc(',',filesave);
    			fmt=fmt+lung; //fmt punta al successivo formato di tipo metadato(%s,%n..)
    			if(isspace(*fmt)==0)
    			{
    				printf("errore3");//trattamento errore, non c'è lo spazio dopo il nome di metadato
    			}
    			fmt++;
    			if(*fmt=='%')
    			{
    				fmt++;
    				switch(*fmt)
    				{
    					case 's':
    						sval=va_arg(ap,char*);
    						scritti=fprintf(filesave,"%s,",sval);
    						if (scritti<0)
    						{
    							printf("errore 11");
    						}
    						fmt++;
    						break;
    					case 'n':
    						fval=va_arg(ap,double);
    						scritti=fprintf(filesave,"%f,",fval);
    						if (scritti<0)
    						{
    							printf("errore 12");
    						}
    						fmt++;
    						break;
    					case 'd':
    						t=va_arg(ap,struct tm*);
    						tx=mktime(t);
    						if (tx == (time_t) (-1))
          					{
          						printf ("Errore! %ld\n", (long int) tx); //trattamento errore data da rivedere
         					}
        					scritti=fprintf(filesave,"%d/%d/%d,",t->tm_mday,t->tm_mon+1,t->tm_year+1900);
    					if (scritti<0)
    					{
    						printf("errore 14");
    					}
        					fmt++;
    						break;
    					default :
    						printf("errore4");//trattamento errore formato sconosciuto
    						break;
    				}
    			}
    			else
    			{
    				printf("errore5");//gestione errore, non c'è % dopo il nome del metadato e lo spazio
    			}
    		
    		}
    		
    	}
    	scritti=fprintf(filesave,"\n");
    	if (scritti<0)
    	{
    		printf("errore15");
    	}
    	close=fclose(filesave);
    	if (close==EOF)
    	{
    		//trattamento errore
    	}
    	va_end(ap);
    	return 0;
    	
    }
    
    
    
    int createfwm(const char *path,const char *mode)
    {
    	FILE* file;
    	FILE* filesave=fopen("save.sav","a"); //il file di salvataggio delle associazioni
    	if ((file=(fopen(path, mode)))==((FILE*)NULL))
    	{
    		return EOF; //gestione errore
    	}
    	fprintf(filesave,"%s\n",path);
    	if(fclose(filesave)==EOF)
    	{
    		return EOF; //gestione errore
    	}
    	return 1;
    }
    
    int main()
    {
    	printf("tuttook0\n");
    	struct tm* tempo=malloc(sizeof(struct tm));
    	tempo->tm_year=150;
    	tempo->tm_mday=15;
    	tempo->tm_mon=5;
    	char car;
    	int a=createfwm("prova.pro","w");
    	int b=createfwm("provi.pri","w");
    	int c=createfwm("prove.pre","w");
    	printf("tuttook1");
    	int d=createf("provu.pru","w","proprietario %srevisione %ndata %d","paolo",5,tempo);
    	printf("tuttook2");
    	
    	return 1;
    }

  5. #5
    Utente di HTML.it L'avatar di braian
    Registrato dal
    Apr 2007
    Messaggi
    35
    up dovrei finire il progetto per lunedì sera, speiamo bene!!

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Il puntatore alla struttura non passa correttamente perche' deve essere specificato meglio il tipo del parametro precedente. Se passi 5, questo non viene inteso come double e sfasa tutto il resto ... devi scrivere

    int d=createf("provu.pru","w","proprietario %srevisione %ndata %d","paolo",5.0,tempo);

    Inoltre, la struttura tm che hai creato va riempita interamente. Puoi azzerarla subito dopo la sua creazione con

    struct tm* tempo=(struct tm*)malloc(sizeof(struct tm));
    memset(tempo, 0, sizeof(struct tm));

    e poi inserire i dati (ad esempio di oggi, e non con anno 150 ...)

    tempo->tm_year=108;
    tempo->tm_mon=1;
    tempo->tm_mday=9;
    No MP tecnici (non rispondo nemmeno!), usa il forum.

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.