{"id":101056,"date":"2019-02-18T07:00:00","date_gmt":"2019-02-18T22:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=101056"},"modified":"2019-03-12T23:57:17","modified_gmt":"2019-03-13T06:57:17","slug":"20190218-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190218-00\/?p=101056","title":{"rendered":"How can I check in Win32 whether a Unicode character is any kind of digit?"},"content":{"rendered":"<p>Suppose you have a Unicode code unit <code>wchar_t<\/code> and you want to know whether it represents a numeric digit. If you have <a HREF=\"http:\/\/icu-project.org\">the ICU library<\/a>, you can check if its code point&#8217;s <code>u_charType<\/code> is <code>U_DECIMAL_DIGIT_NUMBER<\/code>. But what about plain Win32? <\/p>\n<p>For Win32, you can use the <code>Get&shy;String&shy;TypeW<\/code> function to obtain properties for each code unit. <\/p>\n<pre>\nbool IsUnicodeDigit(wchar_t ch)\n{\n    WORD type;\n    return GetStringTypeW(CT_CTYPE1, &amp;ch, 1, &amp;type) &amp;&amp;\n           (type &amp; C1_DIGIT);\n}\n<\/pre>\n<p>We ask the <code>Get&shy;String&shy;TypeW<\/code> function for the <code>CT_<\/code><code>CTYPE1<\/code> value for one character, passing an output buffer of size 1. We then check whether the result says that it is a digit. <\/p>\n<p>The <code>Get&shy;String&shy;TypeW<\/code> function produces a 16-bit value for each provided code unit. There are more than 16 things you can ask about, so they are broken into groups, and you specify which group you want. Group&nbsp;1 contains the basic classifications that support POSIX functions like <code>isdigit<\/code> and <code>isalnum<\/code>. <\/p>\n<p>Here&#8217;s one way it could be done. (I&#8217;m not saying this is how it actually is done.) <\/p>\n<table CLASS=\"cp3\" BORDER=\"1\" CELLPADDING=\"3\" STYLE=\"border-collapse: collapse\">\n<tr>\n<th>C runtime<\/th>\n<th>Category flags<\/th>\n<th>Win32 function<\/th>\n<\/tr>\n<tr>\n<td><code>isalnum<\/code><\/td>\n<td><code>C1_ALPHA | C1_UPPER | C1_LOWER | <br>C1_DIGIT<\/code><\/td>\n<td><code>IsCharAlphaNumeric<\/code> <a HREF=\"http:\/\/archives.miloush.net\/michkap\/archive\/2007\/06\/19\/3396819.html\">sort of<\/a><\/td>\n<\/tr>\n<tr>\n<td><code>isalpha<\/code><\/td>\n<td><code>C1_ALPHA | C1_UPPER | C1_LOWER <\/code><\/td>\n<td><code>IsCharAlpha<\/code> <a HREF=\"http:\/\/archives.miloush.net\/michkap\/archive\/2007\/06\/19\/3396819.html\">sort of<\/a><\/td>\n<\/tr>\n<tr>\n<td><code>isblank<\/code><\/td>\n<td><code>C1_BLANK<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>iscntrl<\/code><\/td>\n<td><code>C1_CNTRL<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>isdigit<\/code><\/td>\n<td><code>C1_DIGIT<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>isgraph<\/code><\/td>\n<td><code>C1_ALPHA | C1_UPPER | C1_LOWER | <br>C1_DIGIT | C1_PUNCT<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>islower<\/code><\/td>\n<td><code>C1_LOWER<\/code><\/td>\n<td><code>IsCharLower<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>isprint<\/code><\/td>\n<td><code>C1_ALPHA | C1_UPPER | C1_LOWER | <br>C1_DIGIT | C1_PUNCT | C1_BLANK<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>ispunct<\/code><\/td>\n<td><code>C1_PUNCT<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>isspace<\/code><\/td>\n<td><code>C1_SPACE<\/code><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>isupper<\/code><\/td>\n<td><code>C1_UPPER<\/code><\/td>\n<td><code>IsCharUpper<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>isxdigit<\/code><\/td>\n<td><code>C1_XDIGIT<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/table>\n<p><b>Bonus reading<\/b>: <a HREF=\"http:\/\/archives.miloush.net\/michkap\/archive\/2007\/06\/11\/3230072.html\">The difference between C1_SPACE-ing out and drawing a C1_BLANK<\/a>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ask for its character type.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-101056","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Ask for its character type.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/101056","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=101056"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/101056\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=101056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=101056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=101056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}