PDA

Visualizza la versione completa : [C++] Leggere file di testo


VisRoboris
25-01-2011, 23:43
Ss, so che l'argomento stato gi affrontato svariate volte,
ma vi chiedo di aiutarmi a correggere il mio codice per migliorare nel c++.
Con questa funzione dovrei leggere la prima linea di testo da un file txt


char* FileTextReadFirstLine(FILE* file)
{
char byte;
int i = 0;
//con il prossimo loop salvo in i la lunghezza
//della prima linea nel file txt
while(!feof(file)) {
//Leggo un char dal file
fread(&byte,sizeof(char),1,file);
if(byte==13) break;
i++;
}
//Fino a qui il codice funziona, ritorna correttamente la lunghezza della prima linea.
//Adesso posso creare il mio array di char da riempire, rileggendo il file.
char* line = (char*) malloc(sizeof(char)*(i+1));
//i+1 per il null terminated char.
//Prima risetto a 0 la posizione nel file
fseek(file,0,SEEK_SET);
int a;
for(a=0;a<=i;a++) {
fread(line+a,sizeof(char),1,file);
}
*(line+a) = '/n'; //null-termino l'array
return(line);
}
In seguito, con cout << line; scopro che line stata riempita di byte strani!
che errore ho fatto?

VisRoboris
25-01-2011, 23:55
dopo diversi tentativi ho scoperto che ho sbagliato qualcosa nel terminare la stringa, perch sizeof(ritorno_di_funzione) mi da 24 invece di 11! (provato con un file txt), eppure boh.. mi sembra giusto..

shodan
26-01-2011, 00:07
A parte che qui di C++ non c' niente. Questa linea:


*(line+a) = '/n'; //null-termino l'array

sbagliata ( e il compilatore dovrebbe dare almeno uno warning dato che sono due caratteri, non uno).
Dev'essere:


*(line+a) = NULL; //null-termino l'array

In generale, per, l'intero impianto mi sembra :afraid: :afraid: :afraid:

VisRoboris
26-01-2011, 11:38
char* FileTextReadLine(FILE* file)
{
unsigned char byte;
int i = 0; char* line = new char;
while(true) {
if(feof(file)) return(NULL);
fread(&byte,sizeof(unsigned char),1,file);
if(byte==13) break;
line[i++] = byte;
char* newb = new char;
memcpy(&line[i],newb,sizeof(newb));
delete newb;
line[i] = NULL;
}
return(line);
}
Grazie, mo funziona.
L'intero impianto ti fa paiura perch si tratta di allocazione di memoria dinamica, senza che poi venga liberata a fine funzione?
In quale altro modo potrei fare per creare un array dinamico di char?

shodan
26-01-2011, 14:03
Adesso che l'hai sistemata fa un po' meno :afraid: :zizi:
Per ci sono ancora cose che non vanno.
line un puntatore a un singolo char non a un array di char, quindi usarlo con le [] sbagliato.
Questa istruzione:


line[i++] = byte;

Dovrebbe essere:


*line = byte;

Errore che poi prosegui anche in:


char* newb = new char;
memcpy(&line[i],newb,sizeof(newb));

perch newb un puntatore, e una sizeof di un puntatore da la dimensione di un puntatore, non di quello a cui punta. In questo caso la dimensione 4 (per 32bit) oppure 8 (per 64 bit).
In pratica stai forzando la memcpy a copiare 4/8 bytes, vale a dire oltre il limite massimo di line.
Corretto sarebbe:


memcpy(line,newb,sizeof(char));

ma inutile per due motivi:
1) basta fare *line = *newb;
2) cosa contiene newb? Lo crei, ne copi il contenuto indefinito da un'altra parte e poi lo cancelli.


line[i] = NULL;

qui vai a scrivere in una locazione che non esiste per quando scritto sopra.

Una possibile alternativa per fare quello che ti serve questa:


char* FileTextReadLine(FILE* file)
{
unsigned char byte;
int char_read;
int count=0;
do {
char_read = fgetc(file);
if ( char_read == '\n') break;
count++; // caratteri letti.
} while (c != EOF); // Fine file?
fseek(file,0,SEEK_SET);
char* line = new line[count];
int read_byte = fread(line, count,1,file);
line[read_byte]=NULL;
return line;
}

Per tutto questo C. In C++ tutto si risolve in tre o quattro righe.

Loading