Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 22-10-2008, 17:00   #1
anyanka
Senior Member
 
L'Avatar di anyanka
 
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
[C++]lettura da istream e crash dell'applicazione

Salve a tutti, avrei bisogno di una mano:
sto sviluppando una piccola applicazione in C++ che legga (per ora) file xml, come parser uso expat.
Per passare i dati al parser apro il file con un istream, conto i caratteri, quindi lo resetto e eseguo una get che mette tutto in un array di caratteri di dim. uguale al numero ricavato precedentemente e a partire da un puntatore (char * buffer) che poi passo al parser xml.
Ora la questione è: con i file piccoli (ho provato fino a 300 caratteri circa) funziona...
con i file grandi (circa 103000 caratteri ma anche già con 14000 dà problemi) va tutto in crash, generando anche un report di errori di windows sia facendo il run da eclipse, sia facendo partire direttamente l'eseguibile.

Dov'è il problema? è troppo grande il buffer?

Codice:
#include <cstdio>
#include <iostream>
#include <fstream>
#include "C:/MinGW/Include/Expat 2.0.1/source/lib/expat.h"

using namespace std;

/* ************* LETTURA FILE XML ATTRAVERSO UN PARSER OTTENUTO CON LA LIBRERIA EXPAT **********/


const int MAX_NOME_FILE = 100 ;


/* prima di tutto devo definire gli ElementHandler */

void start_tag(void *userData, const XML_Char *name, const XML_Char **atts);

void end_tag(void *userData, const XML_Char *name);

void data_handler (void *userData, const XML_Char *s, int len);

XML_Parser parser = XML_ParserCreate("UTF-8");
/* 		PROCEDURA:
 * 1)leggo il file aprendolo con uno stream
 * 2)conto il num di caratteri che contiene
 * 3)creo il parser
 * 4)parso tutto il file passando il numero di caratteri ottenuti dalla conta
 */

int main(){
	string nomeFile ;	//nome del file richiesto da input
	char file[MAX_NOME_FILE] ;
	char * fp;
	ifstream inputFile ;	// stream di input
	int num_caratteri = -1;	//numero di caratteri contenuti nel file

	XML_SetElementHandler(parser, start_tag, end_tag);
	XML_SetCharacterDataHandler(parser, data_handler);
	cout << "**********Programma per la lettura di un file XML********** " << endl;
	cout << "Inserire il percorso del file da leggere " << endl;
	cin >> nomeFile ;
		/* apertura del file */
	fp = strcpy(file, nomeFile.c_str());
	inputFile.open(fp);
	assert(inputFile);
		/* conteggio caratteri */
	while(!inputFile.eof()){
		inputFile.get() ;
		num_caratteri++ ;
	}
	cout << "Il file contiene " << num_caratteri << " caratteri" << endl;
	/* resetto i flag dello stream per poter ricominciare la lettura */
	inputFile.clear();
	inputFile.seekg(0, ios::beg);
	
	/* procedura di parse */
	cout << "          *******************" << endl;

	int ris; // risultato del parser
	char * buffer;

	inputFile.get(buffer, num_caratteri, EOF);   // <----si blocca qui
	system("PAUSE");
	ris = XML_Parse(parser, buffer, num_caratteri-1, 0);
	system("PAUSE");
	if(ris == 0){
		XML_Error errore =	XML_GetErrorCode(parser);
		int riga = XML_GetCurrentLineNumber(parser);
		int colonna = XML_GetCurrentColumnNumber(parser);
		cout << XML_ErrorString(errore) << "\nriga num: " << riga <<"\ncolonna num: " << colonna << endl;
	}
	else {
		cout << "parse eseguito." << endl;
	}
	inputFile.close();
	XML_ParserFree(parser);
	system("PAUSE");
	return 0;
}

void start_tag(void *userData,
        const XML_Char *name,
        const XML_Char **atts) {
	/* gestore dello start tag */
	cout << "trovato start tag: " << name << endl;
	int num_att =  XML_GetSpecifiedAttributeCount(parser) ;
	cout << "attributi: " << num_att/2 << endl;
	if(num_att != 0){
	for(int i=0; i<num_att; i++) {
		cout << "attributo :  " << atts[i] << " = " ;
		i++ ;
		cout << atts[i] << endl;
	}
	}
}

void end_tag(void *userData,
        const XML_Char *name){
	/* gestore dell'end tag */
	cout << "\nchiusura tag " << name << endl;
}


/* mi fa vedere tutto quello che c'è dopo uno start tag e fino alla fine del file */
void data_handler (void *userData, const XML_Char *s, int len){
	//string stringa = string(s);
	//cout << "lunghezza stringa temporanea : " << stringa.length() << "  stringa: " << stringa << endl;

}
sì.. me ne ero dimenticata...
__________________
~ Notebook: Dell Studio 1537 - Intel Core 2 Duo T6400 @ 2,00 GHz ~
~ Cel: Nokia 5230 ~ Console: Nintendo Wii

"La menopausa è quando i cacciatori ubriachi sparano alla cicogna che porta i bebè..."

Ultima modifica di anyanka : 22-10-2008 alle 17:06.
anyanka è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 17:02   #2
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Se posti il codice "incriminato" è più facile aiutarti.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 17:09   #3
anyanka
Senior Member
 
L'Avatar di anyanka
 
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
sì l'ho aggiunta adesso..

praticamente con i file grandi conta i caratteri e quando arriva all'istruzione

inputFile.get(buffer, num_caratteri-1, EOF)

va in crash

EDIT: ho fatto qualche altra prova: sopporta fino a circa 3600 caratteri.. dai 3612 in poi va in crash
__________________
~ Notebook: Dell Studio 1537 - Intel Core 2 Duo T6400 @ 2,00 GHz ~
~ Cel: Nokia 5230 ~ Console: Nintendo Wii

"La menopausa è quando i cacciatori ubriachi sparano alla cicogna che porta i bebè..."

Ultima modifica di anyanka : 22-10-2008 alle 17:29. Motivo: fatto altre prove
anyanka è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 23:19   #4
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
C'è qualche motivo per cui vuoi leggere tutto il file con una sola lettura ?
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 09:36   #5
anyanka
Senior Member
 
L'Avatar di anyanka
 
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
sì...perché (almeno per quello che ho capito fino ad ora) il parser poi troverebbe errori nel momento in cui il testo si divide tra un blocco e l'altro...non saprei proprio come dirgli "se il file non è finito aspetta e attaccaci l'altro blocco prima di segnalare errori"
__________________
~ Notebook: Dell Studio 1537 - Intel Core 2 Duo T6400 @ 2,00 GHz ~
~ Cel: Nokia 5230 ~ Console: Nintendo Wii

"La menopausa è quando i cacciatori ubriachi sparano alla cicogna che porta i bebè..."
anyanka è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 13:37   #6
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Quote:
Originariamente inviato da anyanka Guarda i messaggi
sì...perché (almeno per quello che ho capito fino ad ora) il parser poi troverebbe errori nel momento in cui il testo si divide tra un blocco e l'altro...non saprei proprio come dirgli "se il file non è finito aspetta e attaccaci l'altro blocco prima di segnalare errori"
L'ultimo parametro del metodo XML_Parse indica se stai passando l'ultimo blocco del file che può essere impostato a eof dello stream:
Codice:
int XMLPARSEAPI XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);


void Parse(const string & data, int isFinal)
{
	if (!XML_Parse(parser, data.data(), data.length(), isFinal))
	{
		stringstream s;
		s << XML_ErrorString(XML_GetErrorCode(parser)) << " At line " << XML_GetCurrentLineNumber(parser);
		throw exception(s.str().c_str());
	}
}

Ultima modifica di tomminno : 23-10-2008 alle 13:39.
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 14:13   #7
anyanka
Senior Member
 
L'Avatar di anyanka
 
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
vero! ma come lo gestisco?
da quello che si evince dagli errori è la get che dà problemi, prima ancora di arrivare all'istruzione "XML_Parse(....)"
__________________
~ Notebook: Dell Studio 1537 - Intel Core 2 Duo T6400 @ 2,00 GHz ~
~ Cel: Nokia 5230 ~ Console: Nintendo Wii

"La menopausa è quando i cacciatori ubriachi sparano alla cicogna che porta i bebè..."
anyanka è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 14:21   #8
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Non ci butterei la mano sul fuoco, ma mi viene da pensare che la get ti dia errore perché stai leggendo oltre la porzione del file bufferizzata.
Leggi quindi riga per riga, senza calcolare la dimensione del file prima. Ogni riga la passi XML_Parse.

Edit: non avevo visto l'orrore: ma i buffer non si allocano più ?

char * buffer = new char[num_caratteri+1];

inputFile.get(buffer, num_caratteri, EOF); // <----si blocca qui
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 14:30   #9
anyanka
Senior Member
 
L'Avatar di anyanka
 
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
OMG!! mi sembrava mancasse qualcosa
comunque va bene anche char * buffer = new char[num_caratteri] tanto l'eof non devo considerarlo...
evidentemente per pochi caratteri andava bene...per gli altri non allocava abbastanza spazio...

Grazie mille!
__________________
~ Notebook: Dell Studio 1537 - Intel Core 2 Duo T6400 @ 2,00 GHz ~
~ Cel: Nokia 5230 ~ Console: Nintendo Wii

"La menopausa è quando i cacciatori ubriachi sparano alla cicogna che porta i bebè..."
anyanka è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 14:34   #10
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Ma il carattere di fine stringa suppongo tu lo debba considerare
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 14:45   #11
anyanka
Senior Member
 
L'Avatar di anyanka
 
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
se metto un carattere in più il parser mi dà errore perché dopo una nuova linea - evidentemente - si aspetta un tag che non trova.. quindi per quello che mi serve va bene così
se poi mi darà altri errori saprò dove andare a mettere mani ...
__________________
~ Notebook: Dell Studio 1537 - Intel Core 2 Duo T6400 @ 2,00 GHz ~
~ Cel: Nokia 5230 ~ Console: Nintendo Wii

"La menopausa è quando i cacciatori ubriachi sparano alla cicogna che porta i bebè..."
anyanka è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 14:59   #12
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Non vedo come la lunghezza del buffer possa andare ad influire sul parser. Tu devi passare la lunghezza precedente al parser non quella con il +1 Il +1 serve solo per riservare spazio per il carattere di fine stringa.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 23-10-2008, 15:19   #13
anyanka
Senior Member
 
L'Avatar di anyanka
 
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
allora ricapitolando, il programma funziona se:

- inizializzo num_caratteri = 0;
- li conto
- creo il buffer con char * buffer = new char[num_caratteri+1]
- passo alla get num_caratteri
- decremento num_caratteri di 1
- passo il nuovo valore al parser

se cambio anche una sola di queste condizioni non funziona più...
salvo il fatto che posso usare la dichiarazione ... new char[num_Caratteri] e funziona lo stesso...

__________________
~ Notebook: Dell Studio 1537 - Intel Core 2 Duo T6400 @ 2,00 GHz ~
~ Cel: Nokia 5230 ~ Console: Nintendo Wii

"La menopausa è quando i cacciatori ubriachi sparano alla cicogna che porta i bebè..."
anyanka è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 04:32.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v