0

I'm trying to find out what the expected encoding of wcwidth() argument is. The man page says absolutely nothing about this, and I wasted hours trying to find out what it is. Here's an example, in C:

#include <stdio.h>
#include <wchar.h>

void main()
{
    wchar_t c = L'h';
    printf("%d\n", wcwidth(c));
}

I want to know how should I encode this character literal so that this program prints 2 instead of -1.

Here's a Rust example:

extern "C" {
    fn wcwidth(c: libc::wchar_t) -> libc::c_int;
}

fn main() {
    let c = 'h';
    println!("{}", unsafe { wcwidth(c as libc::wchar_t) });
}

Similarly I want to convert this character constant to wchar_t (i32) so that this program prints 2.

Thanks.

UPDATE: Sorry for my wording, I made this sound specific to C's long char literals. I want to encode character literals in any language as a 32-bit int so that when I pass it to wcwidth I get a right answer. So my question is not specific to C or C's long char literals.

UPDATE 2: I'd also be happy with another function like wcwidth that is better specified (and maybe even platform independent). E.g. one that takes UTF-8 encoded character and returns number of cols needed to render it in a monospace terminal.

sinan
  • 6,809
  • 6
  • 38
  • 67
  • 1
    [This Linux manual page](http://man7.org/linux/man-pages/man3/wcwidth.3.html) says that "[t]he behavior of `wcwidth()` depends on the `LC_CTYPE` category of the current locale." So it very much depends on your locale settings. – Some programmer dude Oct 01 '19 at 12:51
  • I understand that it's locale-dependent, and I want to know how a char is encoded given encoding. For example I have `LC_CTYPE="en_US.UTF-8"` and I wan to know how should I encode the char in example. – sinan Oct 01 '19 at 14:11

1 Answers1

2

You need to add support for _XOPEN_SOURCE and also you need to set your locales.

Try this:

#define _XOPEN_SOURCE 700

#include <stdio.h>
#include <locale.h>
#include <wchar.h>

int main(void)
{
    setlocale(LC_CTYPE, "");

    wchar_t c = L'h';

    printf("%d\n", wcwidth(c));
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • If defined, `_XOPEN_SOURCE` should be defined to a number like 700, not blank. – R.. GitHub STOP HELPING ICE Oct 01 '19 at 13:39
  • @R.. are you sure?, according to [feature_test_macros](https://linux.die.net/man/7/feature_test_macros) is fine to leave it blank or to set a value `< 500` – David Ranieri Oct 01 '19 at 13:44
  • See https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_01_02: "An XSI-conforming application shall ensure that the feature test macro _XOPEN_SOURCE is defined with the value 700 before inclusion of any header." – R.. GitHub STOP HELPING ICE Oct 01 '19 at 13:47
  • 1
    @DavidRanieri: The man page is unclear. I suspect what they're trying to get at is that there were ancient versions of the standard that just wanted it defined, not caring about value, but if you do that you're essentially requesting an ancient version of the standard, and may get different behavior or missing functionality relative to modern versions. – R.. GitHub STOP HELPING ICE Oct 01 '19 at 14:00