Ответ 1
Вторая строка должна читать FILE *f = fmemopen(s, strlen(s), "r");
. Как указано, fmemopen
имеет поведение undefined и может возвращать NULL
, что приводит к сбою getwc()
.
Изменение строки fmemopen()
и добавление проверки для NULL
исправляет сбой, но не соответствует цели OP.
Кажется, что широкая ориентация не поддерживается в потоках, открытых с помощью fmemopen()
, по крайней мере для библиотеки GNU C. Обратите внимание, что fmemopen
не определен в стандарте C, а в POSIX.1-2008 и недоступен для многих систем (например, OS/X).
Вот исправленная и расширенная версия вашей программы:
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
int main(void) {
const char *s = "foo bar foo";
FILE *f = fmemopen((void *)s, strlen(s), "r");
wchar_t c;
if (f == NULL) {
printf("fmemopen failed: %s\n", strerror(errno));
return 1;
}
printf("default wide orientation: %d\n", fwide(f, 0));
printf("selected wide orientation: %d\n", fwide(f, 1));
while ((c = getwc(f)) != WEOF) {
printf("read %lc (%d 0x%x)\n", c, c, c);
}
return 0;
}
Запуск в linux:
default wide orientation: -1
selected wide orientation: -1
Нет вывода, WEOF
возвращается немедленно.
Объяснение для fwide(f, 0)
на странице руководства linux:
СИНТАКСИС
#include <wchar.h> int fwide(FILE *stream, int mode);
Когда
mode
равно нулю, функцияfwide()
определяет текущую ориентациюstream
. Он возвращает положительное значение, еслиstream
является широкосимвольным, то есть, если допускается широкополосный ввод-вывод, но char I/O запрещен. Он возвращает отрицательное значение, еслиstream
является байт-ориентированным, то есть если char I/O разрешен, но широкоформатный ввод-вывод запрещен. Он возвращает ноль, еслиstream
еще не имеет ориентации; в этом случае следующая операция ввода-вывода может изменить ориентацию (к байту, ориентированному, если это операция ввода/вывода char, или к широкосимвольной ориентации, если это широкоформатная операция ввода-вывода).Как только поток имеет ориентацию, он не может быть изменен и сохраняется до тех пор, пока поток не будет закрыт.
Когда
mode
отличное от нуля, функцияfwide()
сначала пытается установить ориентациюstream
(для широкосимвольной ориентации, если режим больше 0 или байт ориентирован, еслиmode
меньше 0). Затем он возвращает значение, обозначающее текущую ориентацию, как указано выше.
Поток, возвращаемый fmemopen()
, байт-ориентирован и не может быть изменен на широкоформатный.