Kodowanie polskich znaków - problem głębszy niż mogłoby się wydawać

0

Kod programu w C :

#include <stdio.h>
#include<stdlib.h>
#include<wchar.h>
#define DT 100000
#define DL_ACSII 1024

int pobierz(int tab[], int dltab)
{
	FILE *fp;
	fp=fopen("tekst.txt","r");
	int i=0;
	while(1)
	{
		if(i==dltab)
			return (-1);
		tab[i]=getc(fp);
		
		if(tab[i]==EOF)
			return (i);
		
		++i;
	}
}
void drukuj(int tab[],int dn)
{
	int i=0;
	while(i<dn)
	{
		putchar(tab[i]);
		++i;
	}
}

int licz_znaki(int tab[],int ile[],int dn)
{
	int wewl=0;
	for(int k=0;k<DL_ACSII;++k)
	{
		ile[k]=0;
	}	
	
		for(int k=0;k<dn;++k)
	{
		++ile[tab[k]];
		++wewl;
		
	}	
	return wewl;
}

void drukuj_znaki(int ile[])
{
	printf("\n*********\n");
	int k=0;
	while(k<DL_ACSII)
	{
		if(ile[k]>0)
		{
			switch(k)
			{
				case 10:
					printf("enter");
					break;
				case 32:
					printf("spacja");
					break;
				case 9:				
					printf("tab");
					break;
				default:
					putchar(k);
					printf("%d",k);
					break;			
			}
			printf(":%d\n",ile[k]);
		}
		++k;
	}
		
}


int main()
{
	int x=0;
	int dn=0;
	int tab[DT];
	int ile[DL_ACSII];
	dn=pobierz(tab,DT);
	if(dn<0)
		printf("tl;dr\n");
	else
	{
		drukuj(tab,dn);
		x=licz_znaki(tab,ile,dn);
		drukuj_znaki(ile);
	}
printf("%d\n%d\n",dn,x);
	

}

Zawartość pliku tekst.txt :

ąąćóżaaa

Wyjście programu :

ąąćóżaaa

*********
enter:1
a97:3
�133:2
�135:1
�179:1
�188:1
�195:1
�196:3
�197:1
14
14

Wynik działania komendy xxd tekst.txt :

00000000: c485 c485 c487 c3b3 c5bc 6161 610a       ..........aaa.

Kodowanie polskich znaków:
https://www.utf8-chartable.de/unicode-utf8-table.pl?start=256&names=-&utf8=dec

Wygląda na to że, program (putchar()?) czyta sobie po 32 bity i każdą z tych 32 interpretuje i wypisuje na ekran.
Jaka szkoda że, "zwykłe" znaki zajmują 32 bity podczas gdy polskie 64.
Programik dzieli kod polskiego znaku na dwie części, które potem interpretuje i wypisuje oczywiście jako bzdury.
Jako początkujący proszę Was o radę jak temu zaradzić :')

0

Problem wydaje się głębszy, a jest płytki.
W UTF-8 długość znaków ma od 1 do 6 (praktycznie do 4) bajtów.
Ty rozdzielasz te bajty, więc konsola nie rozumie, co ma wypisać, bo to co wypisujesz nie jest poprawnym UTF-8.
Radzę poczytać o kodowaniu UTF-8 na wiki.

https://en.cppreference.com/w/c/string/multibyte/mbtowc
https://en.cppreference.com/w/c/string/multibyte/mbrtowc

0

Windows czy *nix? I "zwykłe" znaki (popularnie znane jako ASCII) zajmują 7 bitów (najstarszy bit jest zawsze 0), wchar to UTF-16 (na Windzie IIRC, na *niksach nie mam pojęcia).

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