c++ - 当格式包含非 ASCII 字符时 sprintf 不起作用

标签 c++ gcc android-ndk printf clang

针对 i386 arch 编译时,以下对 sprintf 的调用失败。使用 Android NDK。我尝试过使用 GCC 和 clang 进行编译,结果是一样的。我正在使用 android-ndk-r10e (使用 GCC 将 APP_STL 设置为 gnuSTL_shared,使用 clang 将 APP_STL 设置为 c++_shared)。当为具有相同配置的 ARM 进行编译时,以及当我为带有 GCC 5.2 的 i386 Linux 进行编译时,它的工作原理与预期一致(我?)。

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

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

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

另一方面,这工作得很好:

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

我很困惑。

最佳答案

这是已知的 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 - Google Android NDK 的替代分支,该问题已得到解决。如果由 CrystaX NDK 10.3.1 构建,上面的示例可以正常工作:

strlen(buf)=5

关于c++ - 当格式包含非 ASCII 字符时 sprintf 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35354221/

相关文章:

c++ - 使用 Directx 11 的 obj 文件格式

c++ - GCC:libstdc++。so:添加sybols时出错:格式错误的文件

android - 如何通过 JNI 正确地将 YUV_420_888 图像缓冲区从 Java 传递到 OpenCV,考虑步幅/填充

c++ - 像 C# 一样在 Qt 中锁定对象

c++ - ZMQ请求发送保证

linux - 从 linux 共享库中剥离调试信息

assembly - MIPS 汇编器提示 PIC 为 "Branch out of range"

android - 无法访问 WallpaperService 中从 Java 传递的 native 代码中的 AAssetManager

c++ - 确定指向常量的指针是否指向常量对象?

c - 为什么以下代码在使用 gcc 和 g++ 编译时会给出不同的结果?