当格式包含非ASCII字符时,sprintf不起作用

时间:2016-02-12 03:14:52

标签: c++ gcc android-ndk printf clang

编译为i386 arch时,对sprintf的以下调用失败。使用Android NDK。我尝试用GCC和clang编译,结果是一样的。我正在使用android-ndk-r10e(APP_STL设置为gnustl_shared与GCC,c++_shared与clang)。当使用相同的配置为ARM编译时,它的作用是( I?),此外,当我使用GCC 5.2编译i386 Linux时。

int n = sprintf(buf, "\xc0%s", "test"); // n == 0, strlen(buf) == 0

调用之后,buf为空,而不是包含预期的char序列“\ xc0test”。 sprintf似乎忽略了第一个非ASCII字符后的所有内容。以下代码将“test”写入buf,省略了最后一个字节:

sprintf(buf, "%s\xc0", "test"); // strlen(buf) == 4

另一方面,这很好用:

sprintf(buf, "%s", "test\xc0"); // strlen(buf) == 5

我很困惑。

1 个答案:

答案 0 :(得分:2)

这是众所周知的Android问题。问题在于Android libc实现(Bionic),这在符合标准方面相当不完整。特别是,Bionic stdio实现不能正确支持非ASCII字符。

这个简单的测试在由Android NDK r10e构建时打印strlen(buf)=4

#include <stdio.h>
#include <string.h>

int main()
{
    char buf[256];
    sprintf(buf, "%s\xc0", "test");
    printf("strlen(buf)=%d\n", strlen(buf));
    return 0;
}

解决方案:使用CrystaX NDK - 谷歌Android NDK的替代分支,解决问题。如果由CrystaX NDK 10.3.1构建,上面的例子可以正常工作:

strlen(buf)=5