Błąd: "character too large for enclosing character literal type"

0
#include <stdio.h>
#include <string.h>

char Zamien( int KodZnaku, int *TabKodow, char *TabZnakow, int Rozmiar)
{
    int i;

    for (i = 0;  i < Rozmiar; ++i)
        if (KodZnaku == TabKodow[i]) return TabZnakow[i];

    return KodZnaku;
}

void KonwertujNapis( char *Napis, int *TabKodow, char *TabZnakow, int Rozmiar)
{
    unsigned int i;

    for (i = 0;  i < strlen(Napis); ++i)
        Napis[i] = Zamien(Napis[i],TabKodow,TabZnakow,Rozmiar);
}

int main()
{
    int  IloscKodow = 6;

    int  Rozmiar = IloscKodow * sizeof(char);
    int *TabKodow = new int;

    char *TabZnakow = new char;

    char *Napis = strdup("Cze∂Ê ¶wiecie!!! ØyczÍ mi≥ego dnia.");

    TabKodow[0] = 'Ê';     TabZnakow[0] = 'c';  /* tutaj jest ten błąd: character too large for enclosing character literal type */ 
    TabKodow[1] = 'Í';     TabZnakow[1] = 'e';   /* tutaj jest ten błąd: character too large for enclosing character literal type */ 
    TabKodow[2] = '≥';     TabZnakow[2] = 'l';   /* tutaj jest ten błąd: character too large for enclosing character literal type */ 
    TabKodow[3] = '∂';     TabZnakow[3] = 's';  /* tutaj jest ten błąd: character too large for enclosing character literal type */ 
    TabKodow[4] = '¶';     TabZnakow[4] = 'S'; /* tutaj jest ten błąd: character too large for enclosing character literal type */ 
    TabKodow[5] = 'Ø';     TabZnakow[5] = 'Z';/* tutaj jest ten błąd: character too large for enclosing character literal type */ 

    printf("Napis Latin2:  \"%s\"\n",Napis);

    KonwertujNapis(Napis,TabKodow,TabZnakow,IloscKodow);

    printf("Napis ASCII:   \"%s\"\n",Napis);

    return 0;
}  

Czy mógłby mnie ktoś nakierować dlaczego dostaje błąd wymieniony w tytule posta ?

1

Chary to znaki ASCII, w kodzie masz Unikod czy coś podobnego, w każdym razie używany symbol ma więcej niż jeden bajt, więc nie ma go jak wepchnąć do chara. Używaj wchar, jeśli tego potrzebujesz.

3

Kompilator dokładnie pokazuje Ci co powoduje bład
screenshot-20170302231239.png
Musisz jawnie powiedzieć kompilatorowi, że to unicode:

TabKodow[0] = u'Ê';

I tak dalej dla każdego Twojego znaczka. Inaczej będzie on traktowany jako zwykły, jedno bajtowy znak ASCII.
Poza tym, źle inicjalizujesz tablice:

fasolus napisał(a):
    int *TabKodow = new int;

    char *TabZnakow = new char;

Powinieneś podać rozmiar, naprzykład w ten sposób

int *TabKodow = new int[6]

A potem zwolnić pamięć, gdy już przestanie być potrzebna

delete[] TabKodow;
2
TabKodow[0] = 'Ê';     TabZnakow[0] = 'c';  /* tutaj jest ten błąd: character too large for enclosing character literal type */ 

Czy mógłby mnie ktoś nakierować dlaczego dostaje błąd wymieniony w tytule posta

Booo... bo plik masz pewnie zapisany w UTF-8. Takie Ê w UTF-8 zajmuje więcej niż jeden bajt (zapewne 2, nie chce mi się sprawdzać), więc nie mieści się w jednej zmiennej char i nie może być użyty jako “character literal” bez prefiksu (u, u8, L, popróbuj).

Kodowanie UTF-8 ma to do siebie, że „śmieszne” znaczki zajmują więcej niż jeden char (maksymalnie chyba do czterech).

3
several napisał(a):

Powinieneś podać rozmiar, naprzykład w ten sposób

int *TabKodow = new int[6]

A potem zwolnić pamięć, gdy już przestanie być potrzebna

delete[] TabKodow;

Tak naprawdę to powinieneś używać std::vector, zamiast bawić się w nagie new[] i delete[].

1

Nie uwalniasz pamięci ani po new ani po strdup. Osatecznie możesz napisać strdupa, wtedy użyta będzie alloca i pod linuchem to będzie śmigać. Pamięć sama się uwolni po wyjściu z bloku.
Do sprawdzenia wielkości multibyte char pod linuchem możesz użyć mbrlen.

Pzdr.

1

Poza błędami kompilacji, jest więcej problemów, wynikających z braku zrozumienia jak działa kodowanie znaków.
Gdybyś kompilował swój kod tak by użyte było by kodowanie Windows-1250 to wtedy jeden znak, w tym polskie z ogonkami, są kodowane za pomocą jednego bajtu, który mieści się w char.
Wtedy twój kod miałby szanse na prawidłowe działanie.

Błąd kompilacji wskazuje, że masz ustawione inne kodowanie, prawdopodobnie UTF-8, które ma zmienną długość znaków.
W tym kodowaniu wszystkie znaki z zakresu ASCII mają jeden bajt a wszystkie inne więcej.
Przykładowo "Ś" w UTF-8 ma dwa bajty: C5 9A https://unicode-table.com/en/015A/
To oznacza, że twój kod powinien być świadomy zmiennej długości znaków i robić porównania po ustaleniu długości znaku.

Do twojej wiadomości: zwykle usuwanie "akcentów i ogonków" z napisów nie wykonuje się ręcznie, ale korzysta z gotowych bibliotek.
W standardowym C++ da się niektóre rzeczy zrobić z kodowaniem (usuwanie z liter akcentów być może też), ale jest to tak upierdliwe i trudne, że albo większość ludzi nie wie że się da, albo woli prościej i wygodniej użyć niestandardowych bibliotek np http://site.icu-project.org/ .

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0