【问题标题】:sprintf not working when format contains non-ASCII characters当格式包含非 ASCII 字符时,sprintf 不起作用
【发布时间】:2016-02-12 03:14:52
【问题描述】:

以下对sprintf 的调用在为 i386 架构编译时失败。使用安卓 NDK。我试过用 GCC 和 clang 编译,结果是一样的。我正在使用android-ndk-r10e(APP_STL 设置为gnustl_shared GCC,c++_shared 和clang)。在为具有相同配置的 ARM 进行编译时,以及在使用 GCC 5.2 为 i386 Linux 进行编译时,它的工作原理与 (I?) 一样。

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

我很困惑。

【问题讨论】:

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


    【解决方案1】:

    这是已知的 Android 问题。问题在于 Android libc 实现(仿生),它在符合标准方面相当不完整。尤其是仿生 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
    

    【讨论】:

    • 这对我来说非常有效。我看到你是 CrystaX 的创造者,所以非常感谢你。 stdlib.h 不包含 labs,但这很容易解决。
    • 嗯,实际上stdlib.h 包含labs 定义。如果您遇到问题,请随时在我们的问题跟踪器上提交带有最小可重现案例的错误 - tracker.crystax.net/projects/ndk
    猜你喜欢
    • 2021-02-24
    • 1970-01-01
    • 2021-10-15
    • 2013-08-30
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多