Si la pregunta es solo '9'
(o uno de los dígitos romanos ), solo restar '0'
es la solución correcta. Si le preocupa algo por lo que iswdigit
devuelve distinto de cero, sin embargo, el problema puede ser mucho más complejo. El estándar dice que iswdigit
devuelve un valor distinto de cero si su argumento es "un código de dígitos de dígitos decimales [en el actual local]". Lo cual es impreciso, y lo deja a la configuración regional a definir exactamente lo que significa. En la configuración regional "C" o la configuración regional "Posix" , el estándar "Posix", al menos, garantiza que solo los dígitos romanos de cero a nueve se consideran dígitos decimales (si lo entiendo correctamente), entonces si re en la configuración regional "C" o "Posix" , simplemente restando '0' debería funcionar.
Presumiblemente, en una configuración regional Unicode, este sería cualquier carácter que tenga la categoría general Nd
. Hay un número de estos.La solución más segura sería simplemente para crear algo como (variables aquí con duración estática):
wchar_t const* const digitTables[] =
{
L"",
L"\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669",
// ...
};
//! \return
//! wch as a numeric digit, or -1 if it is not a digit
int asNumeric(wchar_t wch)
{
int result = -1;
for (wchar_t const* const* p = std::begin(digitTables);
p != std::end(digitTables) && result == -1;
++ p) {
wchar_t const* q = std::find(*p, *p + 10, wch);
if (q != *p + 10) {
result = q - *p;
}
return result;
}
Si usted va esta manera:
- que sin duda quiere descargar el archivo desde
UnicodeData.txt
el consorcio Unicode ("Uncode Character Database" — esta página tiene unos enlaces a la vez los datos de archivos Unicode y un explination de las codificaciones utilizadas en ella), y
- posiblemente escriba un analizador simple de este archivo para extraer la información automáticamente (p. cuando hay una nueva versión de Unicode) — el archivo está diseñado para el análisis programático simple .
Por último, tenga en cuenta que las soluciones basadas en ostringstream
y istringstream
(esto incluye boost::lexical_cast
) no se trabajo, ya que las conversiones se utilizan en corrientes se definen solamente utilizan los dígitos romanos. (Por otro lado, podría ser razonables para restringir su código para sólo los dígitos romanos. En cuyo caso, la prueba se convierte en if (wch >= L'0' && wch <= L'9')
, y la conversión se realiza restando simplemente L'0'
— siempre suponiendo que el de la codificación nativa de las constantes de carácter ancho en su compilador son Unicode (el caso, soy bastante seguro, tanto de VC++ como de g ++). O simplemente asegúrese de que la configuración regional sea "C" (o "Posix", en una máquina Unix).
EDIT: se me olvidó mencionar:., si está haciendo ningún tipo de programación seria Unicode, debe buscar en ICU Manejo Unicod e correctamente es extremadamente no trivial, y que han una gran cantidad de funcionalidad ya implementado.
¿Tiene un carácter '9' y quiere convertirlo en el dígito '9'? –
@Daren Sí, esa es la idea. –
Si solo tenía ASCII, también podría hacer 'peek & 0xF' – Raze