Fórum Debian

Versão Completa: [Resolvido] Programas com String 'ç'
Você está atualmente visualizando uma versão simplificada do conteúdo. Visualizar a versão completa com formatação.
fiz um programa em c com gtk, neste programa eu digito uma string num GtkEntry e ele me mostra em outro a string com os caracteres em ordem inversa.

tudo funciona, porem se digito 'ç' ele mostra um quadrado no lugar do caracter (no outro GtkEntry), e no terminal aparece
Código:
(gtk_invertstr:4572): Pango-WARNING **: Invalid UTF-8 string passed to pango_layout_set_text()
Bom dia,

Por favor poste a parte do código que está dando erro para analisarmos.

Até mais...
Segue o codigo

Código:
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
* main.c
* Copyright (C) Matheus Maldi 2012 <[email protected]>
*
gtk-invertstr is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gtk-invertstr is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <config.h>
#include <gtk/gtk.h>




/* For testing propose use the local (not installed) ui file */
/* #define UI_FILE PACKAGE_DATA_DIR"/gtk_invertstr/ui/gtk_invertstr.ui" */
#define UI_FILE "src/gtk_invertstr.ui"
#define TOP_WINDOW "window"

/* Signal handlers */
/* Note: These may not be declared static because signal autoconnection
* only works with non-static methods
*/

/* Called when the window is closed */
void
destroy (GtkWidget *widget, gpointer data)
{
    gtk_main_quit ();
}

static GtkWidget*
create_window (void)
{
    GtkWidget *window;
    GtkBuilder *builder;
    GError* error = NULL;

    /* Load UI from file */
    builder = gtk_builder_new ();
    if (!gtk_builder_add_from_file (builder, UI_FILE, &error))
    {
        g_critical ("Couldn't load builder file: %s", error->message);
        g_error_free (error);
    }

    /* Auto-connect signal handlers */
    gtk_builder_connect_signals (builder, NULL);

    /* Get the window object from the ui file */
    window = GTK_WIDGET (gtk_builder_get_object (builder, TOP_WINDOW));
        if (!window)
        {
                g_critical ("Widget \"%s\" is missing in file %s.",
                TOP_WINDOW,
                UI_FILE);
        }
    g_object_unref (builder);
    
    return window;
}

GString*
invert_string(const gchar* str)
{
    GString* result = g_string_new (str);
    
    int beg, end;
    for (beg = 0, end = result->len-1;
         beg < end; beg++, end--)
    {
        gchar temp = result->str[beg];
        result->str[beg] = result->str[end];
        result->str[end] = temp;
    }

    return result;
}

void
entry1_changed(GtkWidget *widget, gpointer data)
{
    GtkEntry* entry1 = (GtkEntry*)widget;
    GtkEntry* entry2 = (GtkEntry*)data;

    GString* str_inverted =
        invert_string (gtk_entry_get_text(entry1));

    g_print(str_inverted->str);
    gtk_entry_set_text (entry2, str_inverted->str);
    
}

int
main (int argc, char *argv[])
{
    GtkWidget *window;


    
    gtk_init (&argc, &argv);

    window = create_window ();
    gtk_widget_show (window);

    gtk_main ();
    return 0;
}

pelo que andei observando, o 'ç', 'á', 'ã' fazer o quadrado com X na conversão

andei debugando o codigo, e percebi que 'ç' = '\303\247' (o ç ocupa 2 caracteres, assim como os outros citados acima), quando faço eu inverto, ele inverte o \303 e \247, tornando um caractere que não existe.
vc esta usando que encode ? UTF-8 ou ascii?
(23/04/2012 15:30)funakoshi Escreveu: [ -> ]vc esta usando que encode ? UTF-8 ou ascii?

não sei te informar. apenas declarei o GString, e estou pegando os caracteres, o que descobri é que o 'ç', 'á' e outros caracteres ocupam 2 caracteres.
(25/04/2012 21:37)funakoshi Escreveu: [ -> ]isso é unicode
http://www.av8n.com/computer/utf/font-chart.html

Entendi o funcionamento, o gtk usa UTF, então meu algoritmo de inverter strings é felho, terei que mudar a implementação para tratar os caracteres que ocupam 2 e 3 espaços, por a string "ç" é { '\303', '\247', '\0'} e meu algoritmo inverte o '\303' com '\247' gerando um caracter que não existe.
vc pode checar pelo começo do byte usando operações bytewise

http://en.wikipedia.org/wiki/UTF-8
Hoje resolvi o problema com o seguinte algoritmo

Código:
GString*
invert_string
(const gchar* str)
{
    GString* result = g_string_new (str);

    gssize beg, end;

    for (beg = 0, end = result->len -1; beg < result->len; beg++, end--)
    {
        if (str[beg] >= '\302' && str[beg] <= '\321')
        {
            result->str[end] = str[beg + 1];
            result->str[end - 1] = str[beg];

            beg++; end--;
        }
        else if (str[beg] >= '\341' && str[beg] <= '\357')
        {
            result->str[end] = str[beg + 2];
            result->str[end - 1] = str[beg + 1];
            result->str[end - 2] = str[beg];
            beg += 2; end -= 2;
        }
        else
        {            
            result->str[end] = str[beg];
        }
    }

    return result;
}

poderia ter ficado mais optimizado, pois nesse eu fui inserindo caracter por caracter, mas ta funcionando e fazendo o que tem que ser feito.

Acredito que ainda não esteja resolvendo alguns caracteres, o 'ẽ' tem valor '\341\272\275' e na estava na lista, provavelmente deve ter outros, mas isso é facil resolver.
URL de Referência