You don't need boost to do what you're trying to do, linux actually supports Unicode in C++ as the language intended (Windows is the outlier here)
The problem with the first program is that the character literal (something enclosed by single quotes) must be a single byte, and
è
is not a single byte in UTF-8, which is what linux saves your source code file in. assuming normal configuration.
In fact, clang gives an error here:
1 2
|
test.cc:11:17: error: character too large for enclosing character literal type
cout << letter('è'); // A letter in French...
|
and gcc gives a somewhat worse-worded warning:
1 2 3
|
test.cc:11:17: warning: multi-character character constant [-Wmultichar]
cout << letter('è'); // A letter in French...
^
|
MiiNiPaa is correct, you have to use a wide character or, alternatively, a string
Also, don't use that hideous use_facet
The following works for me:
using wchar_t:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#include <iostream>
#include <locale>
#include <clocale>
bool letter(wchar_t a)
{
return std::isalpha(a, std::locale("fr_CA.utf8"));
}
int main()
{
// either this:
// std::setlocale(LC_ALL, "fr_CA.utf8");
// or this:
std::ios::sync_with_stdio(false);
std::wcout.imbue(std::locale("fr_CA.utf8"));
std::wcout << "letter(" << L'è' << ") returns "
<< std::boolalpha << letter(L'è') << '\n';
}
|
using UTF-8 strings:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#include <iostream>
#include <locale>
#include <clocale>
#include <algorithm>
#include <codecvt>
// test if every character in a UTF-8 string is a letter
bool letters(std::string str)
{
// this part of C++11 didn't come to gcc until version 5.0
// (Microsoft and Clang had it in 2010 though)
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring wstr = conv.from_bytes(str.data());
return std::all_of(wstr.begin(), wstr.end(),
[](wchar_t c){return std::isalpha(c, std::locale("fr_CA.utf8"));});
}
int main()
{
// either this:
// std::setlocale(LC_ALL, "fr_CA.utf8");
// or this:
std::ios::sync_with_stdio(false);
std::cout.imbue(std::locale("fr_CA.utf8"));
std::cout << "letters(" << "è" << ") returns "
<< std::boolalpha << letters("è") << '\n';
}
|
By the way, you're not using anything french-canadian in here, any UTF-8 locale will work. Here's how these programs run on coliru with American English UTF-8:
wide char:
http://coliru.stacked-crooked.com/a/0bce63e9beb5ce05
strings:
http://coliru.stacked-crooked.com/a/2d88de701da9b81f