PDA

Visualizza la versione completa : [C++] Supporto UTF-8 con ncurses


sean_von_drake
17-04-2014, 22:30
ciao a tutti, ho un programma già funzionante che utilizza ncurses per l'interfaccia utente

il problema è che ora devo fare in modo che supporti utf-8 e sono cominciati i guai...

innanzitutto seguendo le varie guide in internet ho iniziato a lavorare con ncursesw e formw anziché i corrispondenti ncurses e form; e fin qui tutto bene

ho utilizzato la funzione setlocale invocandola, come suggerito dalle guide, dopo initscr():

setlocale(LC_ALL, "it_IT.UTF-8");

però quando vado a compilare i campi del form se inserisco lettere accentate queste non vengono salvate correttamente nel buffer dei campi perché questo lavora con const char

qualcuno sa come ci si muove in questi casi? probabilmente è una cavolata ma ci ho perso una giornata senza riuscire a venirne a capo

MItaly
19-04-2014, 00:13
Hai letto qui (http://www.roguebasin.com/index.php?title=Ncursesw)? Da quanto mi pare di capire, la setlocale andrebbe fatta prima di tutto il resto (anche prima di initscr()).

però quando vado a compilare i campi del form se inserisco lettere accentate queste non vengono salvate correttamente nel buffer dei campi perché questo lavora con const char
Non ho capito, cosa intendi? Se lavori in UTF-8 è normale che le stringhe siano dei char...

sean_von_drake
19-04-2014, 09:13
Hai letto qui (http://www.roguebasin.com/index.php?title=Ncursesw)? Da quanto mi pare di capire, la setlocale andrebbe fatta prima di tutto il resto (anche prima di initscr()).

Non ho capito, cosa intendi? Se lavori in UTF-8 è normale che le stringhe siano dei char...

il mio problema è che le funzioni di controllo dei buffer dei campi dei form vogliono degli array di char, mentre io ho delle wstring

MItaly
20-04-2014, 02:30
Se lavori in UTF-8 non devi usare le wstring, quelle servono per lavorare in UTF-16 (su Windows) o UTF-32/UCS-4 (su Linux). Di base se lavori su Linux di solito non devi fare nulla di particolare per UTF-8, praticamente tutto lavora già così di suo.

sean_von_drake
22-04-2014, 23:16
lavoro sia su linux che su windows... per capirci ecco quello che inserisco:
23832

ed ecco quello che ottengo:

23833

il codice che preleva il valore dal buffer del campo del form è ad esempio:

nome = field_buffer(field[0], 0);

dove nome è una string.

sean_von_drake
12-09-2014, 14:51
se a qualcuno può interessare, sono riuscito a produrre un codice funzionante che stampa caratteri accentati ecc. usando ncursesw:




#include <cstdlib>
#include <string>
#include <ncursesw/ncurses.h>
#include <ncursesw/form.h>

using namespace std;

int main( int argc , char **argv ) {

WINDOW * main_window;
string test;

setlocale(LC_ALL, "it_IT.UTF-8");

if( ( main_window = initscr() ) == NULL ) {

fprintf( stderr , "impossibile inizializzare ncurses" );

return EXIT_FAILURE;

} else {

FIELD *fields[4];
FORM *my_form;
int ch;
int i;

cbreak();
noecho();
keypad( stdscr , TRUE );

fields[0] = new_field( 1 , 12 , 3 , 20 , 0 , 0 );
fields[1] = NULL;

set_field_back( fields[0] , A_UNDERLINE );
field_opts_off( fields[0] , O_AUTOSKIP );
set_field_buffer( fields[0] , 0 , test.c_str() );

curs_set( 2 );

my_form = new_form( fields );
post_form( my_form );

mvprintw( 3 , 10 , "test:" );

form_driver( my_form , REQ_FIRST_FIELD );

refresh();

while( ( ch = getch() ) != KEY_F(1) ) {
switch( ch ) {
case KEY_DOWN:
case KEY_RIGHT:
case '\t':
case '\n':
form_driver( my_form , REQ_NEXT_FIELD );
form_driver( my_form , REQ_END_LINE );
break;
case KEY_UP:
case KEY_LEFT:
form_driver( my_form , REQ_PREV_FIELD );
form_driver( my_form , REQ_END_LINE );
break;
case KEY_BACKSPACE:
form_driver( my_form , REQ_PREV_CHAR );
form_driver( my_form , REQ_DEL_CHAR );
break;
default:
form_driver( my_form , ch );
break;
}
}

form_driver( my_form , REQ_NEXT_FIELD );
form_driver( my_form , REQ_END_LINE );

i = 0;

test = field_buffer( fields[0] , 0 );

unpost_form( my_form );
free_form( my_form );
while( fields[i] ) {
free_field( fields[i++] );
}

mvprintw( 10 , 10 , "hai inserito: %s " , test.c_str() );

getch();

delwin( main_window );
endwin();
refresh();

return EXIT_SUCCESS;

}

}

Loading