Tag: widechar

如何避免C中的整数提升?

目前尚不清楚如何使用宽字符API在C中编写可移植代码。 考虑这个例子: #include #include #include int main(void) { setlocale(LC_CTYPE, “C.UTF-8”); wchar_t wc = L’ÿ’; if (iswlower(wc)) return 0; return 1; } 使用-Wconversion选项使用gcc-6.3.0进行编译会发出以下警告: test.c: In function ‘main’: test.c:9:16: warning: conversion to ‘wint_t {aka unsigned int}’ from ‘wchar_t {aka int}’ may change the sign of the result [-Wsign-conversion] if (iswlower(wc)) return 0; ^ 为了摆脱这个警告,我们转换为(wint_t) ,就像iswlower((wint_t)wc) ,但这是iswlower((wint_t)wc)移植的。 以下示例说明了为什么它不可移植。 […]

如何将多字节字符串转换为glibc中fxprintf.c中的宽字符串?

目前, glibc perror源程序中的逻辑是这样的: 如果stderr是面向的,那么按原样使用它,否则使用dup()它并在dup() ‘ed fd上使用perror() 。 如果stderr是面向广域的,则使用stdio-common / fxprintf.c中的以下逻辑: size_t len = strlen (fmt) + 1; wchar_t wfmt[len]; for (size_t i = 0; i < len; ++i) { assert (isascii (fmt[i])); wfmt[i] = fmt[i]; } res = __vfwprintf (fp, wfmt, ap); 通过以下代码将格式字符串转换为宽字符forms,我不明白: wfmt[i] = fmt[i]; 此外,它使用isascii断言: assert (isascii(fmt[i])); 但格式字符串在宽字符程序中并不总是ascii,因为我们可能使用UTF-8格式字符串,它可以包含非7位值。 为什么在运行以下代码时没有断言警告(假设UTF-8语言环境和UTF-8编译器编码)? #include #include #include #include […]

fwprintf省略了广泛的字符

我正在尝试使用Windows上的MinGW C创建宽字符文件,但似乎省略了宽字符。 我的代码: const wchar_t* str = L”příšerně žluťoučký kůň úpěl ďábelské ódy”; FILE* fd = fopen(“file.txt”,”w”); // FILE* fd = _wfopen(L”demo.txgs”,L”w”); // attempt to open wide file doesn’t help fwide(fd,1); // attempt to force wide mode, doesn’t help fwprintf(fd,L”%ls”,str); // fputws(p,fd); // stops output after writing “p” (1B file size) fclose(fd); 文件内容 píern luouký […]

可以将wchar_t提升为wint_t吗?

我看到glibc参考和修订1到C90的一个矛盾。 来自glibc引用的引用说wchar_t可能会被提升为wint_t: 如果将wchar_t定义为char,则由于参数提升,必须将类型wint_t定义为int 但AMD1说: 目前,现有的实现可能有wchar_t为int,wint_t为long,默认促销不会将int更改为long。 基本上,这是由于wchar_t和wint_t是typedef。 因此,我们现在不会将wchar_t提升为wint_t。 有人知道哪一个是正确的吗? 标准是否保证在以下两个程序中转换为unsigned int和int是正确的? (我只是将wint_t和wchar_t替换为它们在glibc中的实际含义)(我只是将wint_t和wchar_t替换为它们在glibc中的实际含义) #include #include int main(void) { setlocale(LC_CTYPE, “en_US.UTF-8”); unsigned int wc; wc = getwchar(); putwchar((int) wc); } – #include #include #include int main(void) { setlocale(LC_CTYPE, “en_US.UTF-8”); int wc; wc = L’ÿ’; if (iswlower((unsigned int) wc)) return 0; return 1; }

为什么没有“unsigned wchar_t”和“signed wchar_t”类型?

char的签名不是标准化的。 因此,有signed char和unsigned char类型。 因此,使用单个字符的函数必须使用可以包含signed char和unsigned char的参数类型(此类型被选为int ),因为如果参数类型为char ,我们将从编译器获取类型转换警告(如果在这样的代码中使用-Wconversion): char c = ‘ÿ’; if (islower((unsigned char) c)) … warning: conversion to ‘char’ from ‘unsigned char’ may change the sign of the result ( 这里我们考虑如果islower()的参数类型为char会发生什么 ) 而没有明确类型转换使其工作的事情是从char到int自动升级。 此外,引入了wchar_t的ISO C90标准没有说明wchar_t的表示。 来自glibc引用的一些引用: 将wchar_t定义为char是合理的 如果将wchar_t定义为char则由于参数提升,必须将类型wint_t定义为int 。 因此, wchar_t可以很好地定义为char ,这意味着必须应用类似于宽字符类型的规则,即,可能存在wchar_t为正的实现,并且可能存在wchar_t为负的实现。 unsigned wchar_t ,必须存在unsigned wchar_t和signed wchar_t类型(出于与unsigned char和signed char类型相同的原因)。 私有通信显示允许实现仅支持> = 0值的宽字符(与wchar_t的签名无关)。 […]

_T()宏更改UNICODE字符数据

我有UNICODE应用程序,我们使用_T(x),其定义如下。 #if defined(_UNICODE) #define _T(x) L ##x #else #define _T(x) x #endif 我知道L被定义为wchar_t,在任何平台上都是4个字节。 如果我错了,请纠正我。 我的要求是我需要L为2个字节。 因此编译器hack我开始使用-fshort-wchar gcc标志。 但是现在我需要将我的应用程序移动到zSeries,在那里我无法看到-fshort-wchar标志在该平台中的效果。 为了让我能够在zSeries上移植我的应用程序,我需要以这样的方式修改_T()宏,即使在使用L ## x并且不使用-fshort-wchar标志之后,我需要获得2byte宽字符data.Can有人告诉我如何更改L的定义,以便我可以在我的应用程序中将L定义为2个字节。

什么是C语言中的“宽字符串”?

我在书中遇到过这个: wscanf(L”%lf”, &variable); 其中第一个参数的类型为wchar_t * 。 这与scanf(“%lf”, &variable); 其中第一个参数是char *类型。 那有什么不同呢? 我之前从未听过“宽字符串”。 我听过一些名为Raw String Literals的东西,它正在打印字符串(不需要像转义序列那样的东西),但那不是在C.