de Windows 1252 est le plus souvent équivalent à latin-1, alias ISO-8859-1: Windows 1252 a juste quelques caractères supplémentaires attribués dans la plage réservée latin-1 128-159. Si vous êtes prêt à ignorer ces caractères supplémentaires et à rester dans latin-1, la conversion est plutôt facile. Essayez ceci:
#include <stddef.h>
/*
* Convert from UTF-8 to latin-1. Invalid encodings, and encodings of
* code points beyond 255, are replaced by question marks. No more than
* dst_max_len bytes are stored in the destination array. Returned value
* is the length that the latin-1 string would have had, assuming a big
* enough destination buffer.
*/
size_t
utf8_to_latin1(char *src, size_t src_len,
char *dst, size_t dst_max_len)
{
unsigned char *sb;
size_t u, v;
u = v = 0;
sb = (unsigned char *)src;
while (u < src_len) {
int c = sb[u ++];
if (c >= 0x80) {
if (c >= 0xC0 && c < 0xE0) {
if (u == src_len) {
c = '?';
} else {
int w = sb[u];
if (w >= 0x80 && w < 0xC0) {
u ++;
c = ((c & 0x1F) << 6)
+ (w & 0x3F);
} else {
c = '?';
}
}
} else {
int i;
for (i = 6; i >= 0; i --)
if (!(c & (1 << i)))
break;
c = '?';
u += i;
}
}
if (v < dst_max_len)
dst[v] = (char)c;
v ++;
}
return v;
}
/*
* Convert from latin-1 to UTF-8. No more than dst_max_len bytes are
* stored in the destination array. Returned value is the length that
* the UTF-8 string would have had, assuming a big enough destination
* buffer.
*/
size_t
latin1_to_utf8(char *src, size_t src_len,
char *dst, size_t dst_max_len)
{
unsigned char *sb;
size_t u, v;
u = v = 0;
sb = (unsigned char *)src;
while (u < src_len) {
int c = sb[u ++];
if (c < 0x80) {
if (v < dst_max_len)
dst[v] = (char)c;
v ++;
} else {
int h = 0xC0 + (c >> 6);
int l = 0x80 + (c & 0x3F);
if (v < dst_max_len) {
dst[v] = (char)h;
if ((v + 1) < dst_max_len)
dst[v + 1] = (char)l;
}
v += 2;
}
}
return v;
}
Notez que je fais aucune garantie sur ce code. Ceci est complètement non testé.
Et comment cela vaut-il mieux que d'utiliser une API testée en appelant MultiByteToWideChar suivi de WideCharToMultiByte? – Sofahamster
"Mieux"? Quelle notion controversée. La question était de le faire dans un appel de fonction au lieu de deux, surtout si les deux sont 'MultiByteToWideChar()' et 'WideCharToMultiByte()'. Mon code fait ça. Je ne prétends pas que c'est _wise_ pour éviter 'MultiByteToWideChar()'. Nitpickingly, on pourrait signaler que mes fonctions évitent l'allocation d'un tampon temporaire. –