En fonction de votre notion de "caractère", cette question peut être plus ou moins complexe.
Tout d'abord, vous devez transformer votre chaîne d'octets en une chaîne de points de code unicode. Vous pouvez le faire avec iconv()
des soins intensifs, bien que si c'est la seule chose que vous faites, iconv()
est beaucoup plus facile, et fait partie de POSIX.
Votre chaîne de points de code unicode pourrait être quelque chose comme une chaîne à terminaison nulle. uint32_t[]
ou, si vous avez C1x, un tableau de char32_t
. La taille de ce tableau (c'est-à-dire son nombre d'éléments, et non sa taille en octets) est le nombre de points de code (plus le terminateur), ce qui devrait vous donner un très bon départ.
Cependant, la notion de "caractère imprimable" est assez complexe, et vous pouvez préférer compter les caractères suivants graphèmes plutôt que des points de code - par exemple, une a
avec un accent ^
peut être exprimée sous la forme de deux points de code unicode ou d'un point de code hérité combiné â
- les deux sont valides, et la norme unicode exige que les deux soient traités de la même manière. Il existe un processus appelé "normalisation" qui transforme votre chaîne de caractères en une version définie, mais il existe de nombreux graphèmes qui ne peuvent pas être exprimés par un seul point de code et, en général, il est impossible de contourner une bibliothèque appropriée qui comprend cela et compte les graphèmes pour vous.
Cela dit, c'est à vous de décider de la complexité de vos scripts et de la rigueur avec laquelle vous voulez les traiter. La transformation en codepoints unicode est un must, tout ce qui est au-delà est à votre discrétion.
N'hésitez pas à poser des questions sur l'unité de soins intensifs si vous décidez d'en avoir besoin, mais n'hésitez pas à explorer le site beaucoup plus simple iconv()
d'abord.