Newsgroup: it.comp.lang.c
Titolo: Leggere carattere newline

Salve a tutti, ho necessità di leggere un file di testo composto da tot 
righe ciascuna delle quali composta da un numero imprecisato di valori. I 
valori sono stati scritti come "%lf" e poi mandati a capo con il carattere 
"\n".
Devo leggere l'iesimo valore (che so, calcolandolo a priori) di ogni riga ma 
siccome non so quanto è lunga la riga pensavo di fare un ciclo do-while.
Il problema mi sorge quando imposto la condizione di "cambio riga": 
while(temp!='\n').
Uso la fscanf per leggere i valori e credo che il problema risieda proprio 
nell'uso di questa funzione, infatti non riconosce il carattere "\n". In 
realtà non so se il problema è la fscanf o se il fatto che legga i valori 
come %lf. Qualcuno sa come dovrei fare?
Stilizzato:
do{
fscanf(fp,"%lf",&temp);
}while((temp!='\n')&&(!feof(fp)));
grazie
mattia
Uso VisualC.NET 

 }while((temp!='\n')&&(!feof(fp)));
Il problema con questo ciclo è che la scanf salta automaticamente i
whitespaces (e newline è considerato tale) iniziali.
La soluzione canonica è quella di leggere un'intera di riga di input
(tipicamente con fgets) e poi fare il parsing del buffer in memoria.
Luca
-- 
"La mia teoria scientifica preferita e` quella secondo la quale gli 
 anelli di Saturno sarebbero interamente composti dai bagagli andati 
 persi nei viaggi aerei." -- Mark Russel

 ...
come ti ha suggerito Luca nell'altro post, devi leggere linea per linea. 
Quindi, per ognuna, fare una scansione alla ricerca dell'ennesimo valore 
(se c'e').
Sotto trovi un esempino per divertirti a fare un po' di prove
Ciao
--- file.dat -----
3.4  62.3  84.2223  99.531
88.3  6.33  284.23
-1  2.43  6.33  284.23
-39.51  838.3  11.3
2  3  2.9e+3
55
--- esempio.c -----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BF_SIZE	1024
int ennesimo_double(int nInd, char *sLine, double *pdRetVal)
{
	int i, bFound = 0;
	const char * const pDelimit = " \t\n"; /* spazi e delimitatori.. */
	*pdRetVal = 0.0;
	for(i = 0; sLine[i]; nInd--)
	{	/* scarta spazi; altrimenti 'i' a fine stringa */
		i += strspn(&sLine[i], pDelimit);
		if(sLine[i])
		{	if(nInd == 0)
			{	bFound = (1 == sscanf(&sLine[i], "%lf", pdRetVal));
				break;
			}
			/* prossimo valore; altrimenti 'i' a fine stringa */
			i += strcspn(&sLine[i], pDelimit);
		}
	}
	return bFound;
}
int main(void)
{
	char bf[MAX_BF_SIZE];
	FILE *fp;
	int n, nInd = 2; /* (0...n) per esempio: se == 2 allora vogliamo il 3^ 
valore di ogni linea */
	int nRetVal = EXIT_FAILURE;
 
	if(!(fp = fopen("file.dat", "r")))
	{	fprintf(stderr, "** Non posso aprire il file dati.\n");
		return nRetVal;
	}
	for(n = 0; fgets(bf, sizeof(bf), fp); n++)
	{	double d = 0.0;
		printf("Linea %d, n. val %d - Valore: ", n+1, nInd+1);
		if(ennesimo_double(nInd, bf, &d))
			printf("%f\n", d);
		else	printf("NON PRESENTE\n");
	}
	if(ferror(fp))
		fprintf(stderr, "** Errore in lettura del file dati.\n");
	else	nRetVal = EXIT_SUCCESS;
	fclose(fp);
	return nRetVal;
}
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com


...
Le faq  qualche volta diventano obsolete se non ci si sta dietro a 
modificarle e  adeguarle all' evoluzione dello standard :-)
Lo standard 99 (7.19.6.1)  dice esplicitamente:
" l   ....or has no effect on a following a, A, e, E, f, F, g, or G 
conversion specifier."
Quindi il convertitore %lf  c' e' anche per la printf & Co.,  salvo che 
... non fa nulla di diverso dia %f,  a  differenza dell' affermazione 
delle faq : "Strictly speaking, %lf is undefined under printf, though 
many systems probably accept it. To be portable, always use %f."
Giorgio

 many systems probably accept it. To be portable, always use %f."
Questa frase delle faq mi sembra sempre utile ed attuale. Magari 
andrebbe solo aggiunta una nota per il c99.
Ciao
[1] a parte il GCC (che pero' non lo supporta completamente) quanti 
compilatori conosci che supportano pienamente il c99? :)


 }
-- 


"Cybertoldo" <cyber...@moc.liamg> ha scritto nel messaggio 
news:ep14v2$opk$1...@registered.motzarella.org...

Vi ringrazio tutti per i suggerimenti e le delucidazioni datemi.
Da buon ignorante non capisco una cosa però. La fgets in questo modo legge 
1024 valori alla volta? Io ho righe di centinaia (a volte migliaia) di 
double e per ogni riga devo prendere uno/due valori. Mi servirà quindi 
sapere in che riga sono oltretutto per fare dei confronti succesivamente...
Mattia

 (ma 
se ne trovano altre simili in rete) per l'allocazione dinamica del 
buffer di linea.
Ma in entrambi i casi [1], per avere successo, dovresti avere un sistema 
con gli int a 32 bit (comunque non a 16) visto che entrambe le funzioni 
(fgets e dyn_fgets) lavorano con dimensioni dei buffer rappresentabili 
con il tipo 'int'.
Ciao
[1] nel 2^ caso perche' la funzione dyn_fgets() e' stata implementata 
con limiti di portabilita': calcola le lunghezze con gli 'int' anziche' 
con i 'long int' - ma un giorno la modifichero'... :)


 1024 valori alla volta?
No, legge una riga di massimo 1024 caratteri (incluso terminatore ed
eventuale newline). Se la riga è più lunga puoi chiamare più volte
fgets; poiché fgets() termina la lettura quando incontra il newline se
l'ultimo carattere letto non è '\n' allora la riga letta è incompleta
(oppure sei alla fine del file).
Non è possibile fare un posizionamento "random" all'interno della riga
visto che non conosci a priori la lunghezza dei singoli campi quindi in
un modo (fgets multiple) o nell'altro (buffer più grande) devi leggere
l'intera riga.
Luca
-- 
This message will self destruct in 5 seconds.