|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
|
[C++] problemi a riconoscere caratteri ASCII
Salve ragazzi, avrei bisogno che mi aiutaste a capire da dove deriva il mio problema:
ho un programmino, creato su win, funzionante, che scrive in un file caratteri che corrispondono a codici (ASCII, unsigned char) che rappresentano altre stringhe. Dovrebbe funzionare anche su linux perchè non uso nessuna funzione specifica per windows (credo!) invece anzichè scrivere i valori che mi aspetto, ne scrive altri [ad esempio dovrebbe scrivere 1 (codice ascii in decimale) e mi ritrovo un 156].... da cosa può dipendere? Il codice è questo: Codice:
const unsigned char FLAG_BYTE = '\xFF' ;
const unsigned char END_OF_VALUES = '\xFE' ;
typedef struct {
string valore;
int num_occorrenze ;
unsigned char codice ;
} VALORI ;
typedef struct {
char * stringa ;
int dim ;
unsigned char flag ; // serve per differenziare un valore che è stato codificato da uno scritto così com'è,
} DATI_OUT ;
............
DATI_OUT contenuto_attributo = recupero_codice_attr(atts[i]) ;
output.write(contenuto_attributo.stringa, contenuto_attributo.dim) ;
output.write((char *)&contenuto_attributo.flag, sizeof(char));
DATI_OUT recupero_codice_attr(string val) {
DATI_OUT dati ;
VALORI valore_corrente ;
if(val.length() >= CARATTERI) {
valore_corrente = ricerca_valore(val) ;
if( valore_corrente.codice != FLAG_BYTE ) {
// new_output << "sizeof(valore_corrente.codice) = " << sizeof(valore_corrente.codice) << " " ;
dati.stringa = (char *)&valore_corrente.codice ;
// oss: nella conversione da unsigned char a char * il dato diventa da 1 a 3 caratteri....(???)
dati.dim = sizeof(valore_corrente.codice) ;
dati.flag = FLAG_BYTE ; // i valori che hanno flag = FLAG_BYTE sono stati codificati
}
else {
dati.stringa = (char *)val.c_str() ;
dati.dim = val.length() ;
dati.flag = END_OF_VALUES ; // ivalori che hanno flag = END_OF_VALUES non sono stati codificati
}
} else {
dati.stringa = (char *)val.c_str() ;
dati.dim = val.length() ;
dati.flag = END_OF_VALUES ;
}
return dati ;
}
__________________
~ 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è..."
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Mar 2009
Città: Bologna
Messaggi: 1174
|
Ma leggi anche da un file i valori?
Hai considerato il fatto che, nei file ASCII, Windows/Dos hanno un CR (carriage return) in piu' nella "andata a capo" rispetto a Unix? E questo passaggio lo giudico un po' dubbio (o almeno non si evince l'uso che ne fai): dati.stringa = (char *)&valore_corrente.codice ; Cioe' associ l'indirizzo di un carattere (char) a un array di carrattei (char *)... e sintatticamente e' corretto... ma poi che fai, lo utilizzi come stringa? (senza che sia null terminated) Ultima modifica di BrutPitt : 26-03-2009 alle 19:45. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
|
Allora approfondisco la spiegazione:
ho un vector di strutture che contiene coppie (stringa, codice) questo codice è un unsigned char che va da 1 a 255. la funzione recupero_codice fa questo: - cerca la stringa nel vector - legge il codice - se il codice è != 255 passa alla struttura risultante dati i valori del codice stesso come stringa (cioè l'istruzione che hai evidenziato) , la lunghezza (dim) ovviamente sarà 1 e il flag byte che serve in un'altra fase... - se il codice è 255 passa direttamente la stringa, dim = alla sua lunghezza e il flag è diverso. Il cast a char * mi serve per andare a scrivere direttamente il valore nella funzione write(char *, len) l'output è un file binario, non di testo, quindi non dovrei avere problemi di a capo o simili... il problema sta proprio nel valore del carattere che su linux viene scritto nel file che in alcuni casi non capisco da dove provenga.
__________________
~ 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è..."
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
dati.stringa = (char *)val.c_str();
Questo non è corretto perché val può cambiare senza che tu te ne renda conto la posizione in cui è allocato il buffer che contiene i caratteri. In quel caso devi fare un'allocazione dinamica: dati.stringa = new char[val.size() + 1]; strcpy(dati.stringa, val.c_str()); Ovviamente dopo quella struttura dati deve essere deallocata. Che funzioni anche senza può anche essere, ma non è corretto. |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
|
Avevo appena fatto questa modifica:
Codice:
DATI_OUT recupero_codice_attr(string val) {
DATI_OUT dati ;
VALORI valore_corrente ;
if(val.length() >= CARATTERI) {
valore_corrente = ricerca_valore(val) ;
if( valore_corrente.codice != FLAG_BYTE ) {
// new_output << "sizeof(valore_corrente.codice) = " << sizeof(valore_corrente.codice) << " " ;
dati.stringa = new char ;
dati.stringa = (char *)&valore_corrente.codice ;
// oss: nella conversione da unsigned char a char * il dato diventa da 1 a 3 caratteri....(???)
dati.dim = sizeof(valore_corrente.codice) ;
dati.flag = FLAG_BYTE ; // i valori che hanno flag = FLAG_BYTE sono stati codificati
}
else {
dati.dim = val.length() ;
dati.stringa = new char[dati.dim] ;
dati.stringa = (char *)val.c_str() ;
dati.flag = END_OF_VALUES ; // ivalori che hanno flag = END_OF_VALUES non sono stati codificati
}
} else {
dati.dim = val.length() ;
dati.stringa = new char[dati.dim] ;
dati.stringa = (char *)val.c_str() ;
dati.flag = END_OF_VALUES ;
}
new_output << *dati.stringa << "- " << dati.dim << " -" << dati.flag << "\n" ;
return dati ;
}
Grazie a tutti!
__________________
~ 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: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
dati.stringa = new char[dati.dim] ;
dati.stringa = (char *)val.c_str() ; Questo è errato proprio dal punto di vista concettuale. Hai un memory leak perché il puntatore alla memoria allocata dinamicamente viene perso. Non dovrebbe assolutamente funzionare meglio, ma al massimo uguale a prima. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
|
hai ragione.. era uguale...con strcpy sembra funzionare....
ma com'è che su win non mi dava problemi? cmq in generale per trasformare una stringa in un char * devo usare sempre strcpy?
__________________
~ 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
|
Dipende dall'uso che ne devi fare...se la devi copiare e ci devi lavorare sopra sì.
Se la devi usare direttamente in forma costante no. Non a caso c_str ritorna un const char *. Su Win non ti dava problemi probabilmente per una diversa implementazione interna della string. |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Feb 2006
Città: Provincia di BA!
Messaggi: 439
|
Fosse per me farei tutto con le stringhe ma ci sono alcune funzioni che richiedono i puntatori a char (come la write ad es.) e mi costringono a fare il cambio.. ecco perché avevo fatto quel pastrocchio prima
comunque 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è..."
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 04:40.



















