|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
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;
}
__________________
~ 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. |
|
|
|
|
|
#2 |
|
Senior Member
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) |
|
|
|
|
|
#3 |
|
Senior Member
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 |
|
|
|
|
|
#4 |
|
Senior Member
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 ?
|
|
|
|
|
|
#5 |
|
Senior Member
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è..."
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
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. |
|
|
|
|
|
|
#7 |
|
Senior Member
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è..."
|
|
|
|
|
|
#8 |
|
Senior Member
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 |
|
|
|
|
|
#9 |
|
Senior Member
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è..."
|
|
|
|
|
|
#10 |
|
Senior Member
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
|
|
|
|
|
|
#11 |
|
Senior Member
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è..."
|
|
|
|
|
|
#12 |
|
Senior Member
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
|
|
|
|
|
|
#13 |
|
Senior Member
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è..."
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:35.






















