Consigli ReadField!

di il
4 risposte

Consigli ReadField!

Salve a tutti! Allora io ho fatto una funzione che prevede la lettura da file di una stringa separata dallo spazio(stop in questo caso).

int readField(FILE * fp, char stop, int maxDim, char * result) // Restituisce 1 se la lettura è andata a buon fine, 0 in caso contrario.
{
	char c;
	int i, success;

	success = i = 0;
	//fgetc(fp); //legge lo spazio precedente, cancella se devi
	c = fgetc(fp);
	if (c == stop || c == '\n' || c == EOF)
	{
		success = 0;
		*result = NULL;
	}
	else
	{
		while (c != stop && c != '\n' && c != EOF && i < maxDim - 1)
		{
			result[i++] = c;
			c = fgetc(fp);
		}
		result[i] = '\0';
		success = 1;
	}
	return success;
}
Secondo voi va bene così o può essere migliorata? Attendo consigli!(Intendo per leggere anche con più spazi eventualmente).

4 Risposte

  • Re: Consigli ReadField!

    I puntatori in entrata andrebbero sempre valutati per stabilire se sono validi.
    Ma poi, sei certo che il puntatore all'oggetto FILE, anche se valido, sia inizializzato con i requisiti corretti per la lettura?

    Il parametro "maxDim" lo scriverei con il tipo size_t. Immagino sia la dimensione del buffer passato con il nome "result".
    Anche l'indice i lo scriverei con il tipo size_t, perché io non conosco la dimensione del buffer. come regola, size_t è consigliabile per gli indici degli array, dei file, e di tutti gli oggetti la cui dimensione non è nota.

    Non vedo la necessità di ricorrere ad un if-else, penso si potrebbe fare il solo ciclo while. Propongo un possibile tentativo, non testato!
    Size_t readField(FILE *fp, char stop, int maxDim, char *result)
    {
    	if ( !fp || !result )
    	{
    		result[0] = '\0';
    		return 0;
    	}
    
    	size_t i = 0;
    	char c = fgetc(fp);
    
    	while ( c != stop && c != '\n' && c != EOF && i < maxDim -1 )
    	{
    		result[i++] = c;
    		c = fgetc(fp);
    	}
    
    	result[i] = '\0';
    	return i;
    }
    Come vedi, ho eliminato il ritorno "success", la funzione ritorna il numero di caratteri scritti, escluso il terminatore nullo. altrimenti zero.
    Altra cosa, che probabilmente già sai, il terminatore di linea '\n' riconosce la nuova linea di testo per i file scritti da sistemi Unix, o anche Windows che usa la successione '\r' '\n', ma non per i file scritti da alcuni sistemi di Apple che utilizzano unicamente '\r'.
  • Re: Consigli ReadField!

    Allora la funzione viene chiamata se e solo se il file != null(conta che deve essere usata all'interno di una funzione che legge da file quindi...)
    Poi maxDim appunto è la dimensione max della stringa. Stop è il carattere con cui la lettura si stoppa ed infine appunto result è la stringa che deve essere letta da file.
    Dimmi... come posso utilizzare la funzione da te riscritta?(intendo nella lettura riga da file)

    Unqualunque ha scritto:


    I puntatori in entrata andrebbero sempre valutati per stabilire se sono validi.
    Ma poi, sei certo che il puntatore all'oggetto FILE, anche se valido, sia inizializzato con i requisiti corretti per la lettura?

    Il parametro "maxDim" lo scriverei con il tipo size_t. Immagino sia la dimensione del buffer passato con il nome "result".
    Anche l'indice i lo scriverei con il tipo size_t, perché io non conosco la dimensione del buffer. come regola, size_t è consigliabile per gli indici degli array, dei file, e di tutti gli oggetti la cui dimensione non è nota.

    Non vedo la necessità di ricorrere ad un if-else, penso si potrebbe fare il solo ciclo while. Propongo un possibile tentativo, non testato!
    Size_t readField(FILE *fp, char stop, int maxDim, char *result)
    {
    	if ( !fp || !result )
    	{
    		result[0] = '\0';
    		return 0;
    	}
    
    	size_t i = 0;
    	char c = fgetc(fp);
    
    	while ( c != stop && c != '\n' && c != EOF && i < maxDim -1 )
    	{
    		result[i++] = c;
    		c = fgetc(fp);
    	}
    
    	result[i] = '\0';
    	return i;
    }
    Come vedi, ho eliminato il ritorno "success", la funzione ritorna il numero di caratteri scritti, escluso il terminatore nullo. altrimenti zero.
    Altra cosa, che probabilmente già sai, il terminatore di linea '\n' riconosce la nuova linea di testo per i file scritti da sistemi Unix, o anche Windows che usa la successione '\r' '\n', ma non per i file scritti da alcuni sistemi di Apple che utilizzano unicamente '\r'.
  • Re: Consigli ReadField!

    La chiami allo stesso modo, come la chiamavi la tua?
    Premetto che avevo sbagliato a scrivere size_t (ci avevo messo la 'S' maiuscola). Inoltre avevo detto che l'avrei usato anche per maxDim ma poi ti ho lasciato "int maxDim", dunque il prototipo corretto sarebbe:

    size_t readField(FILE *fp, char stop, size_t maxDim, char *result);

    Utilizzo:
    	#define CH_SPACE 32
    	size_t size = 1024;
    	char buffer[size];
    	const char *filename = "C:\\miofile.txt";
    
    	FILE *const pfile = fopen(filename, "r");
    	if( pfile == NULL )
    	{
    		// Gestione dell'errore.
    	}
    
    	if ( readField(pfile, CH_SPACE, size, buffer) )
    	{
    		// TODO: qualcosa;
    	}
    	// else ...
    
    Altrimenti si possono contare i caratteri della stringa scritta sul buffer:
    
    	size_t n = readField(pfile, CH_SPACE, size, buffer);
    	if ( n )
    	{
    		// TODO: qualcosa;
    	}
    	// else ...
    
  • Re: Consigli ReadField!

    Okok grazie!
Devi accedere o registrarti per scrivere nel forum
4 risposte