You might want to look at your OS C library, and see what it provides - it may have a function you can call with XS or Inline::C.
The following code ought to work on my (Linux) system, except that it's thinking the characters given in the example aren't printable - and are hence given a length of -1. My manual says "The behaviour of wcwidth depends on the LC_CTYPE category of the current locale", but gives no hint on what to set it to.
$ cat ./uu
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
use Inline 'C';
my $s0 = "Hello, world";
my $s1 = "\x{5fcd}\x{65e0}\x{53ef}\x{5fcd}";
my $s2 = "($s1)";
my $l0 = w_length ($s0);
my $l1 = w_length ($s1);
my $l2 = w_length ($s2);
say "$l0: $s0";
say "$l1: $s1";
say "$l2: $s2";
__END__
__C__
#include <wchar.h>
int w_length(char* str) {
int i;
int length;
char c;
i = 0;
length = 0;
while(c = str[i++]) {
int l;
l = wcwidth(c);
length += l > 0 ? l : 0;
}
return length;
}
$ LC_CTYPE=en_US.UTF-8 perl -CO ./uu
12: Hello, world
0: 忍无可忍
2: (忍无可忍)
So, there's something missing in my solution, but I'm far from a Unicode expert, let alone the provided library on my system, but it maybe something you can use as a start.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|