Newsgroup: it.comp.lang.c
Titolo: errori nell'aprire un file

ciao, ho un errore nell'aprire un file, praticamente questo file ha due
righe,non so se l'errore e' nell fgets o nell'utilizzare la struttura
che ho creato...
vi posto il codice, se sapete dirmi dov'e' l'errore fatelo, perche' non
riesco a capire dov'e'...
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct account
{
	char *ptAccount;
	char *ptPassword;
};
struct account *recuperaAccount();
int main()
{
	struct account *leggi = recuperaAccount();
	printf("Account: %s\n",leggi->ptAccount);
	printf("Password: %s\n",leggi->ptPassword);
	return(0);
}
struct account *recuperaAccount()
{
	struct account *result = (struct account*) malloc(sizeof(struct
account));
	FILE *ptFileAccount = NULL;
	char Account[200] = {'\0'};
    char Password[200] = {'\0'};
	int flag = 0;
	result->ptAccount = NULL;
	result->ptPassword = NULL;
 
	if ((ptFileAccount = fopen("C:\\specifiche.txt", "r")) != NULL)
	{
		for (;;)
		{
			if(!flag) /* e' la prima riga e quindi memorizzo l'account */
			{
				if((fgets(Account,200,ptFileAccount)) == NULL) break;
				result->ptAccount = Account;
				flag += 1;
			}
			else /* e' la seconda riga e quindi memorizzo la password */
			{
				if((fgets(Password,200,ptFileAccount)) == NULL) return (result);
				result->ptPassword = Password;
			}
		}
		return (result);
	}
	else
	{
		printf("Impossibile aprire il file\n");
		return(result);
	}
}
ciao e grazie in anticipo!!!
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

	}
Prova a separare l'apertura dal file dall'if che verifica che il
puntatore non sia NULL.
Sostituisci insomma la riga con l'if con le due seguenti
	ptFileAccount = fopen("C:\\specifiche.txt", "r");
	if (ptFileAccount != NULL)
Per qualche motivo che non mi riesce di capire, il DevC++ 4.01 e il
Borland Turbo C++ 1.01, aprendo il file all'interno dell'if, quasi
sempre (se non sempre) fa casino, nonostante il percorso del file e
tutto quanto il resto siano a posto.
Ho rischiato di fallire un esame all'Università di recente per quella
stramaledetta singolarità...
Poi se posso darti un consiglio (solo per risparmiare qualche
parentesi e rendere un poco (ma proprio poco) più leggibile il
programma.
Invece di scrivere
  ptFileAccount = fopen("C:\\specifiche.txt", "r");
  if(ptFileAccount != NULL)
    esegui svariate operazioni;
  else
  {
    printf("Impossibile aprire il file\n");
    return(result);
  }
Puoi semplicemente scrivere
  ptFileAccount = fopen("C:\\specifiche.txt", "r");
  if(ptFileAccount == NULL)
  {
    printf("Impossibile aprire il file\n");
    return(result);
  }
  esegui svariate operazioni;
E' proprio una modifica da poco, ma ti fa risparmiare un else, qualche
parentesi graffa, e riduce leggermente (ma sempre molto poco) la
possibilità di commettere piccoli errori.
In ogni caso ovviamente dal punto di vista del compilatore le due
soluzioni sono esattamente uguali, quindi se non ti piace la mia
osservazione, cancellala e vivrai ugualmente felice. :-)))
Ciaooo!!!

tutto quanto il resto siano a posto.
Assolutamente impossibile.
-- 
Andrea Laforgia (
walkie...@libero.it
)
"Usenet is a strange place" [Dennis Ritchie]

Assolutamente impossibile.
Provaci

 Provaci
Mi permetto di dirti: riprovaci.
Cio' che dici e' contrario alle regole sintattiche del C,
c'e' di sicuro qualche errore nel metodo che usi per
aprire il file.


Assolutamente impossibile.
Ho provato con il PC di casa il seguente sorgente:
#include <stdio.h>
#define IN_FILE "pippo.txt"
int main(void)
{
  FILE *miofile;
 
  if((miofile = fopen(IN_FILE, "r")) == NULL)
  {
    printf("Impossibile aprire il file");
    return 1;
  }
  fclose(miofile);
  return 0;
}
Come vedi non fa null'altro che aprire un file e richiuderlo (se è
effettivamente stato aperto) o restituire errore in caso di fallimento
(ovviamente il file pippo.txt esiste e si trova nella stessa cartella
dell'eseguibile).
Qui a casa mia funziona perfettamente, mentre all'università è un
terno al lotto, al punto che mi è capitato di perdere intere ore per
stupidissime righe di codice come quella scritta sopra.
Di recente (lunedì) avevo un esame: Algoritmi e programmazione
avanzata. L'esercizio chiedeva di leggere i nomi dei file da riga di
comando e di svolgere alcune operazioni che ometto per brevità.
Bene... ho completato il programma senza farlo partire neppure una
volta, e al momento di iniziare a debuggare non sono MAI riuscito ad
aprire quel file finché non ho separato l'assegnazione dello stream al
puntatore dalla verifica.
A casa ho un Athlon Thunderbird 1400, con mezzo giga di ram DDR, con
Windows 98 SE.
Ho provato con il DevC++ 4.01, e tutto è risultato perfetto.
All'università c'è una macchina analoga, anche se molto meno potente
(analoga nel senso di GUI e software installati).
E' un pentium II 350, con 32 Mb di ram, e Win98 1a edizione.
Il DevC++ (da me installato perché lo preferisco al Turbo C++ 1.01,
per via dell'interfaccia più gradevole e per la presenza del debugger
visuale insight basato su GDB) in quel sistema presenta spesso
problemi nell'apertura dei file che a casa invece non si presentano.
Ho ritenuto perciò utile consigliare una piccola modifica, del tutto
innocua, che per me si è rivelata risolutrice.
 Anche a me ed al mio insegnante (cui ho chiesto aiuto, ad un certo
punto) il fenomeno è risultato misterioso.
Avrei risposto esattamente come te ("assolutamente impossibile") se
non mi fosse accaduto in prima persona.
Cordiali saluti
  Artemio

 dell'eseguibile).
Se vuoi essere sicuro di leggere correttamente da un file di
testo, devi aggiungere la "t" alla modalita' di apertura:
if((miofile = fopen(IN_FILE, "rt")) == NULL)
Come vedi, non c'e' niente di misterioso.


 aprire il file.
Ho avuto dei problemi simili con un vecchio TCC, ma solo WinNT. Aprendo il
file cosi`:
if ((file = fopen(...)) == NULL)
Tutte le operazioni seguenti davano EOF. Aprendolo
file = fopen(...);
if (file == NULL)
...
andava tutto bene. Sara`  contrario alle regole sintattiche del  C ma e`
cosi`. Senza contare quello  che succedeva con i  puntatori a struttura:
l'assegnamento tra puntatore falliva in modo random.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
#include <stdio.h> 
int main(void) {printf("\t\t\b\b\b\b\b\b");
printf("\t\t\b\b\b\b\b\b");return 0;}

                                result->ptPassword = Password;
[cut]
Account e Password sono variabili globali e vengono distrutte all'uscita
dall  funzione recuperaAccount. Tu  pero`  tramite  la struttura  result
resitituisci il loro indirizzo e lo usi nel main. Dovresti fare una cosa
del genere:
result->ptAccount = malloc(strlen(Account) + 1);
assert(result->ptAccount);
strcpy(result->ptAccount, Account);
Idem per la password.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Ci sono le balle , le megaballe e le statistiche".
 Mark Twain

Ho avuto dei problemi simili con un vecchio TCC, ma solo WinNT. Aprendo il
Puo' darsi che sia un'incompatibilita' del vecchio TCC con
Windows NT.


Come vedi, non c'e' niente di misterioso.
Grazie del suggerimento (molto utile), ma veramente questo continua ad
essere _molto_ misterioso per me. :-)
Continuo a non capire bene la differenza. Perché mai l'utilizzo
dell'apertura "rt" dovrebbe darmi qualche vantaggio rispetto a "r"?
Tra l'altro (ho appena verificato) "rt" non è neppure riportata sul
K&R, anche se funziona. E' C99, oppure fa parte delle modifiche alla
proposta di standardizzazione successive al libro, oppure ancora non è
ansi?
Okay... a intuito posso dire "rb" apre un binario in lettura, e perciò
"rt" aprirà un testo. Ma perché il semplice e buon vecchio "r" non
dovrebbe funzionare, o dovrebbe fornire malfunzionamenti sporadici?
IMHO una funzione dovrebbe lavorare rispettare lo standard punto e
basta, non rimandare ad eventuali alternative.

 dovrebbe funzionare, o dovrebbe fornire malfunzionamenti sporadici?
Vedi sopra.


 dei compilatori, potrebbe variare da testo a binario.
Mi  sa  che ti  sbagli. Il  flag  "r"  implica l'apertura  in  modalita`
testo. Per  aprire  in modalita`  binaria  bisogna  esplicitare il  flag
"b". Il flag "t" non esiste.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Al termine di un pranzo di nozze mi hanno dato un
amaro alle erbe cosi' schifoso che perfino sull'etichetta
c'era un frate che vomitava.

"b". Il flag "t" non esiste.
Sei tu che ti sbagli.
"t" esiste eccome, e' previsto e ratificato dallo standard
del linguaggio.  "r" non implica un bel nulla, se non e'
specificata una modalita' di apertura precisa.  
Con C++ Builder, per esempio, si ha: "if a t or b is not
given in the mode string the mode is governed by the global
variable _fmode. If _fmode is set to O_BINARY files are
opened in binary mode. If _fmode is set to O_TEXT they are
opened in text mode.".


 specificata una modalita' di apertura precisa.
7.19.5.3 The fopen function 
1 Synopsis 
#include <stdio.h> 
FILE *fopen(const char * restrict filename, const char * restrict mode); 
2 Description 
The fopen function opens the file whose name is the string pointed to by
filename, and associates a stream with it.
3 The argument 
mode  points  to a  string. If  the  string  is  one of  the  following,
the  file is  open in  the  indicated mode. Otherwise,  the behavior  is
undefined[228])
r	 	open text file for reading 
w 		truncate to zero length or create text file for writing 
a	 	append; open or create text file for writing at 
		end-of-file 
rb 		open binary file for reading 
wb	 	truncate to zero length or create binary file for 
		writing 
ab		append; open or create binary file for writing at 
		end-of-file 
r+	 	open text file for update (reading and writing) 
w+ 		truncate to zero length or create text file for update 
a+	 	append; open or create text file for update, writing at 
		end-of-file
r+b or rb+ 	open binary file for update (reading and writing) 
w+b or wb+	truncate to zero length or create  binary file for update 
a+b or ab+	append; open or create binary file for update, writing at 
		end-of-file
[228]  If  the string  begins  with  one  of  the above  sequences,  the
implementation might  choose to ignore  the remaining characters,  or it
might use them to select different kinds  of a file (some of which might
not conform to the properties in 7.19.2).
Forse "t" c'era  nel C89, ma nel C99 non  c'e`. Se non viene specificato
il flag "b" il file viene aperto in modo testo.
ciao
Kronos
PS: non sto polemizzando, e` solo una puntualizzazione
-- 
Home: 
http://kronoz.cjb.net
Non ho ancora capito se il mio cane e` maschio o femmina:
quando fa la pipi` si chiude in bagno

il flag "b" il file viene aperto in modo testo.
Togli pure il "forse".  Il flag "t" c'e' sempre stato.
Il C99 per ora e' supportato da pochissimi compilatori,
quindi non lo prendo in considerazione, anche perche' non ho
documentazione ufficiale.  Nel caso dell'OP, il problema e'
sicuramente dovuto al fatto che non viene specificato il
modo preciso con cui trattare le informazioni del file.
