我正在尝试从使用 fmemopen
和 char *
创建的流中读取宽字符。
char *s = "foo bar foo";
FILE *f = fmemopen(s,strlen(s),"r");
wchar_t c = getwc(f);
getwc
抛出一个段错误,我使用 GDB 检查过。
我知道这是因为用 fmemopen
打开了流,因为在打开的流上调用 getwc
正常工作。
fmemopen
是否有宽字符版本,或者是否有其他方法可以解决此问题?
最佳答案
第二行应该是 FILE *f = fmemopen(s, strlen(s), "r");
。正如发布的那样,fmemopen
具有未定义的行为,可能会返回 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
。
Linux 手册页中对 fwide(f, 0)
的解释:
SYNOPSIS
#include <wchar.h> int fwide(FILE *stream, int mode);
When
mode
is zero, thefwide()
function determines the current orientation ofstream
. It returns a positive value ifstream
is wide-character oriented, that is, if wide-character I/O is permitted but char I/O is disallowed. It returns a negative value ifstream
is byte oriented, i.e., if char I/O is permitted but wide-character I/O is disallowed. It returns zero ifstream
has no orientation yet; in this case the next I/O operation might change the orientation (to byte oriented if it is a char I/O operation, or to wide-character oriented if it is a wide-character I/O operation).Once a stream has an orientation, it cannot be changed and persists until the stream is closed.
When
mode
is nonzero, thefwide()
function first attempts to setstream
's orientation (to wide-character oriented if mode is greater than 0, or to byte oriented ifmode
is less than 0). It then returns a value denoting the current orientation, as above.
fmemopen()
返回的流是面向字节的,不能更改为面向宽字符。
关于c - 从使用 fmemopen 创建的流中读取宽字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45624195/