我正在使用JNI将c ++后端库集成到Android项目中的项目。
我正在使用SpannableString类,并直接从C ++调用setSpan()函数来进行样式设置,而不必在前端使用Java重新运行代码。
我有一个带有如下标签(如html)的字符串:
”“这是测试{is}斜体{ie},我们正在使用它来演示应用 功能...”显然带有更多文字。
我正在遍历c ++中的所有字符串字符,并保存它们的位置,然后将斜体范围添加到我的SpannableString中。这是我的循环的样子:
int its = 0, fns = 0, crfs = 0;
for(int i = 0; i < buff.size(); ++i){
if(buff[i] != '{')
continue;
string tmp = "";
for(int a = i + 1; a < i + 5; ++a){
if(buff[a] == '}')
break;
tmp += buff[a];
}
if(tmp == "is"){
its = i;
//start of italics.
} else if(tmp == "ie"){
//end of italic tag.
if(its == 0)
continue;
set_spannable(spannable, new_style_obj(italic), its + 4, i);
its = 0;
} else if(tmp == "fn"){
//new footnote tag.
} else if(tmp == "cf"){
//new cross reference tag.
}
}
代码可以编译并完美运行,但是斜体的位置与java字符串中的位置不直接相关。由于某种原因,它会不断增加,直到我的斜体字不应该出现的位置为止。
我已经在Java中运行了相同的循环,并且效果很好:
String buff = sp.toString();
int its = 0;
for(int i = 0; i < buff.length(); ++i){
if(buff.charAt(i) != '{')
continue;
String tmp = "";
for(int a = i + 1; a < i + 5; ++a){
if(buff.charAt(a) == '}')
break;
tmp += buff.charAt(a);
}
System.out.println(tmp);
if(tmp.equals("is")){
its = i;
} else if(tmp.equals("ie")){
if(its == 0)
continue;
System.out.println("Span from " + its + " to " + i);// + //buff.substr(its + 4, (i-4) -its) + "))";
sp.setSpan(new StyleSpan(1), its + 4, i, 1);
// set_spannable(spannable, new_style_obj(italic), its, i);
its = 0;
}
}
tv.setText(sp);
有趣的是,java中的字符串长度总是大于c ++中的字符串长度。
我已经使用strlen(string.c_str())和string.size()测试了它;两者都不会返回与Java调用string.length相同的长度。
任何人都知道导致此差异的原因以及如何解决该差异?是否有在Java中而不是在C ++中读取的字符?
谢谢您的帮助!
更新1:这是标签位置数据>>
C++
Span from 26 to 36
Span from 146 to 152
Span from 466 to 473
Span from 1438 to 1445
Span from 1726 to 1733
Span from 1913 to 1920
Span from 2157 to 2167
Span from 2228 to 2239
Span from 2289 to 2299
Span from 2544 to 2555
Span from 2827 to 2834
Span from 2965 to 2972
Span from 3293 to 3300
Span from 3913 to 3920
Span from 4016 to 4023
Span from 4378 to 4385
Span from 4467 to 4474
Span from 5179 to 5195
Span from 5337 to 5344
Java
Span from 26 to 36
Span from 146 to 152
Span from 462 to 469
Span from 1426 to 1433
Span from 1710 to 1717
Span from 1897 to 1904
Span from 2139 to 2149
Span from 2208 to 2219
Span from 2269 to 2279
Span from 2520 to 2531
Span from 2803 to 2810
Span from 2939 to 2946
Span from 3265 to 3272
Span from 3877 to 3884
Span from 3980 to 3987
Span from 4340 to 4347
Span from 4427 to 4434
Span from 5129 to 5145
Span from 5285 to 5292
答案 0 :(得分:0)
更新后的表与这样的假设一致,即您的字符串有时包含非ASCII字符,在C ++中,这些字符用多个字符表示。
对此没有简单的解决方法。在计数时,minimalistic approach将跳过具有utf8连续位(10
的高两位)的所有字节,即0x80
和0xbf
之间的字节。 / p>
或者,您可以使用从JNI函数GetStringChars()
获得的两字节UCS-16字符串,该字符串精确地再现了Java表示(即,长度在Java和C ++中是相同的),但是具有库支持不佳(没有函数或std :: string可以提供帮助)。
或者您可以使用codecvt_utf8()
将utf8字符串转换为wchar_t