Newsgroup: it.comp.lang.c
Titolo: Strano EOF

Ho difficoltà a capire perchè il codice che segue, oltre nel riversare 
su file un file che prende come argomento, 
inserisce su file anche lo strano carattere
ÿ
prima di scrivere htmlfinish[]
Sicuramente è un mio errore "progettuale", ma, al momento mi sfugge.
Qualcuno sa aiutarmi?
<code>
#include <stdio.h>
char app;
char htmlstart[]="<html><head><title>File di configurazione</title>
</head><body bgcolor=red><hr><pre>";
char htmlfinish[]="</pre><hr></body></html>";
int col, acapo;
FILE *f_in, *f_out;
int main( char argc, char *argv[])
{
if (argc !=3)  {
   printf ("\n\t Converte files di testo in formato HTML\n\n");
   printf("\t utilizzo:\n\t 2html <origine.c> <dest.html>\n");
   exit();
		}	
	if ( 	
	( f_in = fopen ( argv[1] , "r" ) ) &&
	( f_out = fopen ( argv[2] , "w" ) )
	)
 	{
	  fputs( htmlstart, f_out);
 
	  while ( ! feof(f_in ) ) 
	  	{	
 
			app = getc( f_in );
			fputc ( app , f_out );
 
		} 	/*    fine while  */
	}
 fputs( htmlfinish, f_out);
fclose( f_in ); 
fclose( f_out ); 
}	
/****************************************************************
#       Paolo Lulli 					        #	
#       
lul...@tin.it
                                           #
#	
http://theunixplace.com/~entropia/index.html
            #
*****************************************************************/
</code>
Grazie, e... buone feste :-)
PL
-- 
   	 ___      ___  __       ___       ___ ___  ___
	/__/ /	 /__/ /   //_/ /__  /__/ /__ /__  /__/
       /__/ /__ /  / /__ // / ___/ /  / /__ /__  /
 
 
http://theunixplace.com/~entropia/index.html
 
Obviously welcome removing Anti-spam filters to contact me in email :-)

 
Il problema e` qui`. feof() restituisce  1 *dopo* la prima lettura oltre
la fine del file. In pratica, dopo che l'ultimo carattere e` stato letto
feof() restituisce ancora 0. Quindi effettui  di nuovo un getc (oltre la
fine  del file)  e scrivi  il  carattere (che  dovrebbe essere  EOF). La
versione corretta dovrebbe essere questa:
int c; /* int, non char! */
...
while(1) {
	c = getc(f_in);
	if (c == EOF)
		break;
	fputc(c, f_out);
}
Questo metodo di  copia e` pero` abbastanza  lento, potresti considerare
l'uso di un buffer per velocizzarlo.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"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

 prima di scrivere htmlfinish[]
Perché  vai a leggere la fine del file. In queste istruzioni:
|    while ( ! feof(f_in ) )
|
|        app = getc( f_in );
l'feof() ti riporta 0, ma l'EOF viene raggiunto alla successiva istruzione.
Dovresti sostituire con:
    while ((app = getc(f_in)) != EOF)
        fputc (app , f_out );
Stai attento che app dovrebbe essere un int e non un char.
Maurizio.

>l'feof() ti riporta 0, ma l'EOF viene raggiunto alla successiva istruzione.
Grazie ad entrambi, ho risolto 8:-)
ma... perche' deve essere int c e non gia' char c ?
Cordialità, P.
-- 
   	 ___      ___  __       ___       ___ ___  ___
	/__/ /	 /__/ /   //_/ /__  /__/ /__ /__  /__/
       /__/ /__ /  / /__ // / ___/ /  / /__ /__  /
 
 
http://theunixplace.com/~entropia/index.html
 
abviously welcome removing Anti-spam filters to contact me in email :-)

 ma... perche' deve essere int c e non gia' char c ?
Perché la funzione getc() riporta un int. Infatti è definita così:
    int getc(FILE *stream);
Infatti, oltre ad un carattere, può riportare anche altre cose come EOF che
è definito come -1, cioè 0xffffffff.
Se definisci la variabile app come char, l'EOF non ti verrà mai riportato e
non uscirai più dal loop.
Maurizio.

 considerare l'uso di un buffer per velocizzarlo.
le funzioni di I/O del C sono gia' bufferizzate, quindi non c'e' 
bisogno di fare cio'. Probabilmente non otterresti un grande guadagno 
di velocita'.
Occorre anche tenere presente che il buffer delle libreria standard 
molto probabilmente non sara' l'unico. Dopo di quello ci potrebbero 
essere quello del sistema operativo e quello del dispositivo fisico (ad 
esempio hard-disk), quindi...
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 di velocita'.
Vero. Pero`  l'OP   usava  fputc   per  la  scrittura. La   chiamata  ad
una  funzione  e`  un'operazione  relativamente costosa  in  termini  di
prestazioni. Usare putc  (che di solito  e` una macro)  migliorerebbe la
situazione. Cmq,  lo standard  dice che  getc/putc possono  (non devono)
essere implementati come macro, quindi IMHO e` meglio usare fread/fwrite
per copiare blocchi di caratteri.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"La teoria e` quando sappiamo come funzionano le cose ma non funzionano.
 La pratica e` quando le cose funzionano ma non sappiamo perche`.
 Abbiamo unito la teoria e la pratica: le cose non funzionano piu` e non
 sappiamo il perche`." -- A. Einstein

 per copiare blocchi di caratteri.
Di solito fread()/fwrite() sono implementate in termini di 
fgetc()/fputc()... una chiamata di funzione è sempre più veloce della 
latenza minima di un'accesso diretto alla memoria di massa, quindi 
sarebbe inutile o poco vantaggioso implementarle in altro modo.
Fabio Alemagna

 sarebbe inutile o poco vantaggioso implementarle in altro modo.
Questo ragionamento  fila solo considerando poche  chiamate. Nella copia
di un file carattere per carattere  questo non e` piu` vero. Le chiamate
possono  diventare  migliaia o  milioni,  e,  credimi, la  differeza  si
vede. In ogni caso, tutte le funzioni  lavorano sul buffer (sulla RAM in
sostanza) ed i tempi di accesso del disco contano molto poco.
Basta fare qualche semplice prova con questi due programmini:
#include <stdio.h> 
int main () {
	FILE *f, *f2;
	char buff[1024];
	int c;
	f = fopen("orig", "r");
	f2 = fopen("copy1", "w");
	while(fgetc(f) != EOF)
		fputc(c, f2);
	fclose(f2);
	fclose(f);
	return 0;
}
#include <stdio.h> 
int main () {
	FILE *f, *f2;
	char buff[1024];
	int c;
	f = fopen("orig", "r");
	f2 = fopen("copy2", "w");
	while((c = fread(buff, 1, 1024, f)) > 0)
		fwrite(buff, 1, c, f2);
	fclose(f2);
	fclose(f);
	return 0;
}
La  differenza  e`  effetivamente  piccola  per  file  piccoli  (fino  a
300-400KB). Per file piu` grandi (1-4MB) il  secondo e` piu` di 20 volte
piu` veloce del primo. Per file ancora piu` grandi il divario diminuisce
leggermente ma rimane comunque ampio.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Not an editor command: Wq