C format strings get truncated in Android Lollipop

时间:2015-11-12 12:08:03

标签: android java-native-interface string-formatting android-5.1.1-lollipop

I have the following line of C code to format degrees/minutes/seconds as a string.

g_strdup_printf("%d°%d'%d\" %c%c%d°%d'%d\" %c",
    lat_deg,lat_min,lat_sec,latc,sep,lng_deg,lng_min,lng_sec,lngc);

The code is part of a cross-platform app which runs on a couple of platforms, including Linux and Android. Starting with Android Lollipop, the string gets truncated at the first degree sign. Instead of 42°43'44" N 45°46'47" E I just get 42. Indeed strlen reports the string as being 2 characters long.

This code has worked flawlessly on earlier Android versions (at least Gingerbread through KitKat). It also works on Linux, and in the past I have used it successfully on Windows CE and desktop Windows.

What's happening on Lollipop, and how can I resolve it?

1 个答案:

答案 0 :(得分:0)

显然Lollipop在C格式字符串中存在扩展字符(任何超过7位)的问题:

当我用空格替换度数符号时,结果如预期。当我用扩展的ANSI集合中的任何其他字符替换它们时,它们会被截断,就像该字符是\0一样 - 如果我使用正确的转义序列,如\xb0\u00b0,则相同。显然,扩展的ANSI字符给我们带来了麻烦。

当我这样做时

g_strdup_printf("42°43'44\" N 45°46'47\" E");

我得到一个格式正确的字符串。显然这个问题只影响字符串格式化例程,而不是通用字符串 - 这也解释了为什么静态字符串中的坐标可以工作。

在度数标志的格式字符串中添加占位符并将它们作为额外参数传递也没有帮助 - 它们将显示为mojibake并使渲染代码崩溃。

我最终完全绕过字符串格式化例程并执行:

g_strjoin(NULL,
        g_strdup_printf("%d", lat_deg), "°",
        g_strdup_printf("%d", lat_min), "'",
        g_strdup_printf("%d", lat_sec), "\" ",
        g_strnfill(1, latc),
        g_strnfill(1, sep),
        g_strdup_printf("%d", lng_deg), "°",
        g_strdup_printf("%d", lng_min), "'",
        g_strdup_printf("%d", lng_sec), "\" ",
        g_strnfill(1, lngc),
        NULL);