anyanka
22-10-2008, 18:00
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? :help: :help: :help:
#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...
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? :help: :help: :help:
#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...