Skip to content

Instantly share code, notes, and snippets.

@silvioprog
Last active September 6, 2019 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save silvioprog/1d05876811e8b57c05860ddc7f0d8d55 to your computer and use it in GitHub Desktop.
Save silvioprog/1d05876811e8b57c05860ddc7f0d8d55 to your computer and use it in GitHub Desktop.
Convert encoding of given string from CP1252 to UTF-8 in C using iconv(3).
/* Public domain */
/* Author: silvioprog */
/*
Build and test:
$ gcc cp1252_to_utf8.c
$ ./a.out
A função atou() é incrível!
Valgrind dump:
$ valgrind --show-error-list=yes --tool=memcheck --gen-suppressions=all --leak-check=full --leak-resolution=med --track-origins=yes --vgdb=no ./a.out
==22979== Memcheck, a memory error detector
==22979== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22979== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==22979== Command: ./a.out
==22979==
A função atou() é incrível!
==22979==
==22979== HEAP SUMMARY:
==22979== in use at exit: 0 bytes in 0 blocks
==22979== total heap usage: 14 allocs, 14 frees, 35,631 bytes allocated
==22979==
==22979== All heap blocks were freed -- no leaks are possible
==22979==
==22979== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Feel free to use or improve it and have a lot of fun! (:
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <iconv.h>
static char *atou(const char *str) {
char *res, *out, *tmp;
size_t len, obl, ibl, diff;
iconv_t ic;
len = strlen(str);
if (len < 1)
return NULL;
res = NULL;
obl = len;
ibl = len;
ic = iconv_open("UTF-8", "CP1252");
if (ic != (iconv_t) -1) {
res = malloc(len + 1);
if (!res) {
iconv_close(ic);
return NULL;
}
out = res;
while (ibl > 0)
if (iconv(ic, (char **) &str, &ibl, &out, &obl) == -1) {
if (errno == E2BIG) {
diff = out - res;
len += ibl;
obl += ibl;
tmp = realloc(res, len + 1);
if (tmp) {
res = tmp;
out = res + diff;
continue;
}
}
free(res);
res = NULL;
break;
}
iconv_close(ic);
}
if (res) {
len -= obl;
res[len] = 0;
}
return res;
}
int main(void) {
char *str = atou("A fun\xe7\xe3o atou() \xe9 incr\xedvel!");
printf("%s\n", str);
free(str);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment