Проверить, является ли символ русской буквой
Я использую кодировку UTF8 и setlocale(LC_ALL, "russian")
В строке лежат символы, надо найти все, являющиеся русскими буквами. Как это сделать? Я уже пробовал делать строку из этого символа и подобные методы, но если просто "оторвать" символ, записанный в UTF8 от остальной строки, то получится неизвестно что, тк коды часто не влезают в один байт. Единственное решение, которое я нашел, использует std::wstring, но хотелось бы как-нибудь обойтись без него. Возможно ли?
Ответы (1 шт):
Автор решения: avp
→ Ссылка
Вот простой пример, как это сделать
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
// Returns Unicode of cyrillic or 0
// see https://jrgraphix.net/r/Unicode/0400-04FF
int
is_rus_letter (const char *s, int only_rus)
{
if ((*s & 0xe0) != 0xc0)
return 0;
if ((s[1] & 0xc0) != 0x80)
return 0;
uint32_t uc = ((s[0] & 0x1f) << 6) | (s[1] & 0x3f); // 5 bits `s[0]` and 6 bits `s[1]`
if (uc < 0x400 || uc > 0x4ff)
return 0; // not cyrillic
if (only_rus)
if ((uc < 0x410 || uc > 0x44f) && // А - Я; а - я
!(uc == 0x401 || // Ё
uc == 0x451)) // ё
return 0;
return uc;
}
int
main (int ac, char *av[])
{
char s[LINE_MAX + 1];
printf("enter lines (not longer %d bytes)\n", LINE_MAX);
while (fgets(s, LINE_MAX, stdin)) {
int n = 0;
for (int i = 0; s[i]; i++) {
int uc;
if ((uc = is_rus_letter(s + i, 1))) {
n++;
char r[3]; r[0] = s[i], r[1] = s[i + 1]; r[2] = 0;
printf("in pos %d rus 0x%03x '%s'\n", i, uc, r);
}
}
printf("%d rus letters\n", n);
}
return puts("End") == EOF;
}
Если что-то не понятно, спрашивайте