- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
mbrtowc
指定用于处理 s
(多字节字符指针)参数的 NULL
指针,如下所示:
If s is a null pointer, the mbrtowc() function shall be equivalent to the call:
mbrtowc(NULL, "", 1, ps)
In this case, the values of the arguments pwc and n are ignored.
据我所知,这种用法在很大程度上是无用的。如果 ps
没有存储任何部分转换的字符,调用将简单地返回 0 而没有副作用。如果 ps
正在存储一个部分转换的字符,那么由于 '\0'
作为多字节序列中的下一个字节是无效的 ('\0'
只能是字符串终止符),调用将返回 (size_t)-1
和 errno==EILSEQ
。并使 ps
处于未定义状态。
预期的用途似乎是重置状态变量,特别是当 NULL
被传递给 ps
并且内部状态已被使用时,类似于 mbtowc
的状态编码行为,但据我所知,这未在任何地方指定,并且它与 mbrtowc
的存储语义冲突部分转换的字符(如果 mbrtowc
在可能有效的初始子序列后遇到 0 字节时重置状态,它将无法检测到这个危险的无效序列)。
如果 mbrtowc
被指定为仅当 s
为 NULL
时重置状态变量,而不是当它指向 0 字节时,a理想的状态重置行为是可能的,但这种行为会违反书面标准。这是标准的缺陷吗?据我所知,一旦遇到非法序列,绝对没有办法重置内部状态(当 ps
为 NULL
时使用),因此没有正确的程序可以使用 mbrtowc
和 ps==NULL
。
最佳答案
由于无论移位状态如何,'\0' 字节都必须转换为空宽字符(5.2.1.2 多字节字符),并且 mbrtowc()
函数被指定为在以下情况下重置移位状态它转换为宽空字符(7.24.6.3.2/3 的 mbrtowc 函数),调用 mbrtowc( NULL, "", 1, ps)
将重置存储在 中的移位状态
。如果调用 ps
指向的 mbstate_tmbrtowc( NULL, "", 1, NULL)
以使用库的内部 mbstate_t
对象,它将重置为初始状态。有关标准相关部分的引用,请参阅答案的末尾。
我在 C 标准多字节转换函数方面绝对不是特别有经验(我对这种事情的经验一直是使用 Win32 API 进行转换)。
如果 mbrtowc()
处理一个被 0 字节截短的“不完整字符”,它应该返回 (size_t)(-1)
以指示无效的多字节char(从而检测到您描述的危险情况)。在那种情况下,转换/转换状态是未指定的(我认为你基本上已经被那个字符串所淹没了)。尝试转换但包含 '\0'
的多字节“序列”无效,并且永远对后续数据有效。如果 '\0
' 不打算成为转换序列的一部分,那么它不应该包含在可用于处理的字节数中。
如果您处于可能获得部分多字节字符的附加后续字节(例如来自网络流)的情况,则您为部分多字节字符传递的 n
不应该包括一个 0 字节,所以你会得到一个 (size_t)(-2)
返回。在这种情况下,如果您在部分转换过程中传递了 '\0'
,您将失去存在错误的事实并且作为副作用重置 mbstate_t
状态正在使用(无论是您自己的状态还是正在使用的内部状态,因为您为 ps
传入了 NULL 指针)。我想我在这里基本上是在重申你的问题。
不过我认为检测和处理这种情况是可能的,但不幸的是它需要你自己跟踪一些状态:
#define MB_ERROR ((size_t)(-1))
#define MB_PARTIAL ((size_t)(-2))
// function to get a stream of multibyte characters from somewhere
int get_next(void);
int bar(void)
{
char c;
wchar_t wc;
mbstate_t state = {0};
int in_partial_convert = 0;
while ((c = get_next()) != EOF)
{
size_t result = mbrtowc( &wc, &c, 1, &state);
switch (result) {
case MB_ERROR:
// this multibyte char is invalid
return -1;
case MB_PARTIAL:
// do nothing yet, we need more data
// but remember that we're in this state
in_partial_convert = 1;
break;
case 1:
// output the competed wide char
in_partial_convert = 0; // no longer in the middle of a conversion
putwchar(wc);
break;
case 0:
if (in_partial_convert) {
// this 'last' multibyte char was mal-formed
// return an error condidtion
return -1;
}
// end of the multibyte string
// we'll handle similar to EOF
return 0;
}
}
return 0;
}
也许不是理想情况,但我认为这表明它还没有完全坏到无法使用。
标准引用:
5.2.1.2 多字节字符
A multibyte character set may have a state-dependent encoding, wherein each sequence of multibyte characters begins in an initial shift state and enters other locale-specific shift states when specific multibyte characters are encountered in the sequence. While in the initial shift state, all single-byte characters retain their usual interpretation and do not alter the shift state. The interpretation for subsequent bytes in the sequence is a function of the current shift state.
A byte with all bits zero shall be interpreted as a null character independent of shift state.
- A byte with all bits zero shall not occur in the second or subsequent bytes of a multibyte character.
7.24.6.3.2/3 mbrtowc函数
If the corresponding wide character is the null wide character, the resulting state described is the initial conversion state
关于c - mbrtowc 的 s==NULL 案例的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4709498/
我正致力于通过 OAuth 合并外部 API,但对 expires_in 属性的用途有点迷惑。通过阅读,应该对 api token 的使用进行防御性编码,因为您应该预料到 token 在任何时候都可能
有人可以概述或总结一下 Spring 框架上下文中 bean 的用途吗? 我了解标准的 Java bean(没有 arg 构造函数、getter/setter,通常是序列化的),但 Spring be
使用 OpenGL 4.1 和 ARB_separate_shader_objects,我们能够在着色器程序中存储着色管道的不同阶段。众所周知,要使用这些,我们需要将它们附加到程序管道对象,然后绑定(
正如我从文档中了解到的那样,“MoveIteratorFactory”的目的是生成每一步都需要执行的 Action 。 “getSize”方法的移动子集有多大? “createOriginalMove
请解释 CMakeLists.txt 中这一行的目的是什么: 包括(InstallRequiredSystemLibraries) 我在 CMake 示例中看到这一行,但找不到好的解释,为什么我需要它
这里是新手。我仍在尝试理解在多个布局中运行单个进程或目的的概念。 例如,我想在我的申请中添加“提交后”功能。有一个包含标题、内容等文本框的主布局,以及一个链接到另一个布局以选择类别的按钮。我的问题是,
我在看 Box Oauth2.0 View Controller : https://github.com/box/box-ios-sdk-v2/blob/master/BoxSDK/OAuth2/B
我编写了一个将字符串复制到系统剪贴板的 Java 应用程序。构造函数使用 Clipboard.setContents(Transferable contents, ClipboardOwner own
阅读此文后:http://sourcemaking.com/design_patterns/command 我还是不太明白为什么我们需要这个。 最佳答案 想法是,如果命令被封装为对象,那么这些命令可以
我知道 c++ 中的模板是做什么的,但是今天我看到了一些奇怪的代码: template <> void swap(foo &a, foo &b) { a.name = b.name; a.
我不太明白 C# Collections 中 IEnumerator 的用途是什么。它的用途是什么,为什么要使用它? 我试着在线查看 http://msdn.microsoft.com/en-us/l
不幸的是,我今天做了一些代码考古(同时重构了一些旧的危险代码)并发现了这样的小化石: # line 7 "foo.y" 能在里面找到如此古老的宝藏,我完全惊呆了。我在 C 编程的网站上阅读了它。然而,
您能否澄清一下此注释的实际用途? - 如果我们没有使用数据库中的 SQL 表定义定义相应的约束,会发生什么情况。当我们尝试插入时,hibernate 会检查唯一性吗?或者这就是DB的目的吗?如果 hi
我在视频教程中看到过这段代码: const navToggle = ["Menu"].join(""); $(".site-header").prepend(navToggle); 我明白它的基本作用
我想知道这个成员函数的 scroll_to(TextBuffer::iterator& iter, double within_margin = 0)参数 within_margin。 API 是这样
我想知道是否可以将子目录提交到目录例如,假设您有 site.com/directory 可以将子目录提交到目录。我即将开始为希望她的网站在搜索引擎中排名靠前的客户进行一些搜索引擎优化。我知道实现此目的
STL 迭代器的用途是什么?为什么程序员要创造这个概念? 最佳答案 迭代器允许您将算法与容器分开。只要您有开始和结束迭代器,并且知道迭代器的功能(随机访问等),您就可以在迭代器指定的范围内进行操作。例
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&respons
我正在编写代码,使用通用的 linux i2c 驱动程序 linux/i2c-dev.h 实现一个简单的 i2c 读/写功能 我对 ioctl 感到困惑:I2C_SLAVE 内核文档说明如下: You
在尝试克隆可变集合时,我最初的方法是对 mutable.Cloneable 特征使用 clone() 方法。但是,这取决于创建引用副本的 java.Object.clone 实现,而不是深拷贝。通过测
我是一名优秀的程序员,十分优秀!