View Full Version : [C++]Sostituzione di parole accentate. Perchè non funziona?
limpid-sky
20-04-2009, 18:52
Salve,
stavo sperimentando con la classe string ma non riesco a capire perchè questa funzione presa da "Practical programming" di bruce Eckel non funziona.
Faccio leggere un file contenente delle frasi e deve sostituirmi "è caldo" con "is hot";
Non accade nulla perchè non riesce a leggere la "è" e quindi non sostituisce tutto.
Funziona invece per altre stringhe.
Se possibile non vorrei copiare l'oggetto string in un array.
#include <iostream>
#include <fstream>
#include <string>
#include "ReplaceAll.h"
using namespace std;
int main()
{
ifstream ingresso("in.txt");
string s;
string temp;
while (getline(ingresso, s))
{
cout<<s;
temp=temp+s;
}
ingresso.close();
replaceAll(temp,"è caldo","is hot");
ofstream uscita("exit.txt");
uscita<<temp;
uscita.close();
system ("pause");
return 0;
}
//: C03:ReplaceAll.cpp {O}
//#include <cstddef>
#include "ReplaceAll.h"
using namespace std;
string& replaceAll(string& context, const string& from, const string& to)
{
size_t lookHere = 0;
size_t foundHere;
while((foundHere = context.find(from, lookHere))!= string::npos)
{
context.replace(foundHere, from.size(), to);
lookHere = foundHere + to.size();
}
return context;
} ///:~
#include <string>
std::string& replaceAll(std::string& context,
const std::string& from, const std::string& to);
limpid-sky
20-04-2009, 19:32
sembra essere un problema legato a unicode. ma come posso fare per risolverlo?
poichè in inglese le lettere accentate non ci sono quella funzione va bene per l'inglese ma non per l'italiano.
sembra essere un problema legato a unicode. ma come posso fare per risolverlo? salvando il txt in formato ANSI :D
limpid-sky
21-04-2009, 00:12
salvando il txt in formato ANSI :D
Grazie di aver risposto.
sono ignorante come si fa?
o almeno indicami dove vedere.
Per salvare correttamente secondo in ANSI come devo fare?.
Grazie di aver risposto.
sono ignorante come si fa?
o almeno indicami dove vedere.
Per salvare correttamente secondo in ANSI come devo fare?. aprilo con Blocco Note, scegli "Save As..." dal menu File e nella casella "Encoding" seleziona "ANSI".
limpid-sky
21-04-2009, 10:34
Ah intendevi questo.
Per crearlo in questo modo dal terminale del C++ non esiste nulla?
limpid-sky
21-04-2009, 10:54
come posso fargli sostituire ste benedette parole accentate.
Sto impazzendo.
limpid-sky
21-04-2009, 12:20
Forse usando visual c++ e qualche libreria di windows si può fare più rapidamente?
Volevo capire il perchè questo sistema non funziona. Cioè non riesco a capire perchè non legge il carattere "è". Da quello che ho capito sbattendoci la testa fino ad ora è che il carattere "è" non è contenuto nell'ascii standard ma in quello esteso. Essendo il file del blocco note scritto in Ansi forse c'è una relazione tra le due cose.
Una possibile soluzione sarebbe passare per il C.
Copiare una riga dal file in una stringa del C.
vedere carattere per carattere se trova il carattere "è"
Se lo trova sostituirlo con una coppia di caratteri "is"
Ricalcolare la lunghezza della stringa e shiftare tutto.
Insomma una bella porcata.
limpid-sky
21-04-2009, 20:40
UP
Un indicazione?
limpid-sky
22-04-2009, 16:24
nessuna soluzione?
tomminno
22-04-2009, 22:50
nessuna soluzione?
Come hai creato il documento "in.txt"?
Se è in formato UTF8 (e assai probabilmente lo è altrimenti il tuo codice doveva funzionare) dovrai usare MultiByteToWideChar usando come code page CP_UTF8 e usare wchar_t e derivati oppure iconv sotto Linux.
Altrimenti dovresti usare setlocale ma a quanto mi risulta nessun Visual Studio può impostare l'UTF8 come locale (solo VS2003 apparentemente ci riusciva ma era solamente un bug, che dovevano risolvere in VS2005, ma che è ancora prensente in VS2008...), non mi è mai capitato il problema sotto linux perciò non saprei se un setlocale(".65000") è sufficiente.
DanieleC88
23-04-2009, 08:39
Al limite puoi appoggiarti a wcstombs() per la conversione UTF-8 → ANSI e mbstowcs() per la conversione ANSI → UTF-8, mi sembra che sia standard per il C99.
tomminno
23-04-2009, 12:15
Al limite puoi appoggiarti a wcstombs() per la conversione UTF-8 → ANSI e mbstowcs() per la conversione ANSI → UTF-8, mi sembra che sia standard per il C99.
La faccenda è più complicata: wcstombs/mbstowcs convertono da e verso UCS-2, per usare i codepage c'è bisogno di affidarsi a librerie non incluse nello standard (C e C++).
Anche boost ha qualche classe per la gestione dell'utf8 ma non l'ho mai usata.
Nel caso in questione la conversione deve essere molto probabilmente da UTF-8 a Windows-1252 (o ISO-8859-15)
non si fa prima a risalvare il file txt? :huh:
DanieleC88
23-04-2009, 12:54
La faccenda è più complicata: wcstombs/mbstowcs convertono da e verso UCS-2, per usare i codepage c'è bisogno di affidarsi a librerie non incluse nello standard (C e C++).
Anche boost ha qualche classe per la gestione dell'utf8 ma non l'ho mai usata.
Nel caso in questione la conversione deve essere molto probabilmente da UTF-8 a Windows-1252 (o ISO-8859-15)
Hmm, sei sicuro? Non riesco a trovare nessuna informazione che confermi, ma nemmeno che smentisca. :wtf:
tomminno
23-04-2009, 14:03
Hmm, sei sicuro? Non riesco a trovare nessuna informazione che confermi, ma nemmeno che smentisca. :wtf:
Direi sicuro al 99.9%.
Il problema dei Code Page è decisamente una delle cose per cui il C++ fornisce scarsissimo supporto, supporto invece fornito semplicissimamente dal .NET (tra l'altro a vedere il codice della classe Encoding direi che hanno fatto il porting di qualcosa scritto in C, visto che è pieno di puntatori e goto).
Sono queste le cose che fanno apprezzare un linguaggio con una grossa libreria standard altro che la gestione automatica della memoria...
Comunque dicevo wcstombs/mbstowcs utilizzano per le conversioni il codepage definito nel programma tramite le apposite funzioni C/C++ (locale/setlocale).
Il problema è che per l'appunto i compilatori Microsoft non sono in grado di impostare come Code Page l'UTF8 e quindi le funzioni standard non possono essere usate (non conosco altrettanto bene altri compilatori per Windows, ho usato il compilatore Intel solo per applicazioni scientifiche dove non c'erano di questi problemi).
Invece le funzioni del sistema operativo (MultiByteToWideChar/WideCharToMultiByte) consentono di specificare un code page specifico per le conversioni.
tomminno
23-04-2009, 14:11
non si fa prima a risalvare il file txt? :huh:
Quello sicuramente.
Ma metti che (non so se questo è il caso) il programma debba elaborare file scritti da un applicativo .NET (che di default usa UTF8), o modifichi il programma .NET per fargli scrivere in un code page differente o devi adattare la lettura
limpid-sky
23-04-2009, 16:40
Ma il file txt di origine viene generato dal programma in c++ con l'istruzione ofstream quindi non so come lo salva.
Vi dico quello che il programma fa. Apre un file html ne fa il parsing e ne estrae il testo che viene salvato in un file con l'istruzione ofstream. A partire da questo file che viene riaperto il lettura vengono sostituite delle stinghe contenenti la "è" con stringhe in inglese. Tutto qua.
Ho anche provato a fare un file in txt e salvare in ansi ma il problema si presenta lo stesso e le stringhe contententi "è" non vengono sostituite.
Per esempio non viene sostituita la stringa "domani è" "con tomorrow is".
Forse ora è + più chiaro.
tomminno
23-04-2009, 16:51
Vi dico quello che il programma fa. Apre un file html ne fa il parsing e ne estrae il testo che viene salvato in un file con l'istruzione ofstream. A partire da questo file che viene riaperto il lettura vengono sostituite delle stinghe contenenti la "è" con stringhe in inglese. Tutto qua.
E il file html da dove viene? Potrebbe aver benissimo essere specificato un encoding UTF8.
Hai guardato in debug cosa vedi al posto dei caratteri accentati quando leggi l'html?
Ho anche provato a fare un file in txt e salvare in ansi ma il problema si presenta lo stesso e le stringhe contententi "è" non vengono sostituite.
Per esempio non viene sostituita la stringa "domani è" "con tomorrow is".
Forse ora è + più chiaro.
Questo è strano io ho provato il codice che hai postato te e funziona con caratteri accentati, se il file non è UTF8.
limpid-sky
23-04-2009, 16:56
non so usare bene tutti gli strumenti e le mie conoscenze non sono così approfondite. cmq se riesco cerco di postarvi il codice o il file da cui vorrei leggere.
In visual c++ ho realizzato questo.
Praticamente è un programmino che legge la chat di gioco digitale in formato html e ne estrae il testo in html salvandolo in un file .
http://support.microsoft.com/kb/249232
Da questo file poi volevo farmi un programmino a console con codeblocks che traduca frasi del tipo "Il river è" con "***RIVER***" oppure "Il flop è:" con "***FLOP***"
Bearpower
23-04-2009, 19:58
purtroppo non ho molto tempo per illustrarti le problematiche, ma magari dai un'occhiata qua:
http://unicode.org/Public/PROGRAMS/CVTUTF/
ci sono due file ConvertUTF.h e ConvertUTF.c che credo facciano al caso tuo.
In soldoni, converti tutto in UTF16 / UTF32 a seconda di cosa supporta il tuo sistema e poi fai le varie operazioni che ti serve fare.
Purtroppo non penso che tu possa riuscire a convertire una stringa UTF8 in UCS2 senza passare per un buffer temporaneo, che però puoi allocare automaticamente, evitando (troppo) overhead. Fammi sapere se ti risolve qualcosa :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.