Unicode ICU compare与iconv编码的字符串不正确
我尝试使用ICU的compare API比较两个Unicode字符串,其中字符串已通过iconv实用程序转换为UTF16LE 下面是它的代码:Unicode ICU compare与iconv编码的字符串不正确,unicode,icu,iconv,Unicode,Icu,Iconv,我尝试使用ICU的compare API比较两个Unicode字符串,其中字符串已通过iconv实用程序转换为UTF16LE 下面是它的代码: #include <iconv.h> #include <iostream> #include <stdio.h> #include <string.h> #include <errno.h> #include "unicode/coll.h" #include "unicode/utypes
#include <iconv.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "unicode/coll.h"
#include "unicode/utypes.h"
#include "unicode/ucnv.h" /* C Converter API */
#include "unicode/ustring.h" /* some more string fcns*/
#include "unicode/uchar.h" /* char names */
#include "unicode/uloc.h"
#include "unicode/unistr.h"
using namespace std;
using namespace icu;
const size_t BUF_SIZE=1024;
class IConv {
iconv_t ic_;
public:
IConv (const char* to, const char* from)
: ic_(iconv_open(to,from)) {
if ( iconv_t(-1) == ic_ )
cout << "iconv_open failed: " << errno << endl;
}
~IConv ()
{ if ( iconv_t(-1) != ic_) iconv_close(ic_); }
bool convert (char* input, char* output, size_t& out_size) {
size_t inbufsize = strlen(input)+1;
return
(size_t(-1)
!= iconv(ic_, &input, &inbufsize, &output, &out_size))
&& (0U == inbufsize);
}
};
void
icu_compare(UnicodeString str1, UnicodeString str2)
{
UErrorCode success = U_ZERO_ERROR;
Collator *collator = Collator::createInstance("UTF16LE", success);
collator->setStrength(Collator::SECONDARY);
if (collator->compare(str1, str2) == 0) {
cout << "Strings are equal" << endl;
} else {
cout << "Strings are unequal" << endl;
}
}
int main(void)
{
char local_encoding[BUF_SIZE];
char str1[BUF_SIZE];
char str2[BUF_SIZE];
char enc_str1[BUF_SIZE];
char enc_str2[BUF_SIZE];
cout << "Local encoding: " << endl;
cin >> local_encoding;
cout << "String1: " << endl;
cin >> str1;
cout << "String2: " << endl;
cin >> str2;
IConv ic("UTF16LE", local_encoding);
bool ret;
size_t outsize = BUF_SIZE;
ret = ic.convert(str1, enc_str1, outsize);
if (ret == false) {
cout << "iconv failed: " << errno << endl;
}
else {
for ( int i = 0 ; i < (BUF_SIZE - outsize) ; ++i )
if ( enc_str1[i] )
cout << "enc_str1[" << i << "]=[" << int(enc_str1[i]) << "]("
<< enc_str1[i] << ")\n";
}
ret = ic.convert(str2, enc_str2, outsize);
if (ret == false) {
cout << "iconv failed: " << errno << endl;
}
else {
for ( int i = 0 ; i < (BUF_SIZE - outsize) ; ++i )
if ( enc_str2[i] )
cout << "enc_str2[" << i << "]=[" << int(enc_str2[i]) << "]("
<< enc_str2[i] << ")\n";
}
UnicodeString us1 = UNICODE_STRING_SIMPLE(enc_str1);
UnicodeString us2 = UNICODE_STRING_SIMPLE(enc_str2);
cout << "Unicode 1: " << us1.getBuffer() << endl;
cout << "Unicode 2: " << us2.getBuffer() << endl;
icu_compare(us1, us2);
return ret ? 1 : 0;
}
有趣的是,即使输入字符串相同,unicode字符串似乎也不同
但是,当输入字符串不同时,输出为:
$ ./a.out
Local encoding:
ISO_8859-1
String1:
tägelîch
String2:
tägelîck
enc_str1[0]=[116](t)
enc_str1[2]=[-61](▒)
enc_str1[4]=[-92](▒)
enc_str1[6]=[103](g)
enc_str1[8]=[101](e)
enc_str1[10]=[108](l)
enc_str1[12]=[-61](▒)
enc_str1[14]=[-82](▒)
enc_str1[16]=[99](c)
enc_str1[18]=[104](h)
enc_str2[0]=[116](t)
enc_str2[2]=[-61](▒)
enc_str2[4]=[-92](▒)
enc_str2[6]=[103](g)
enc_str2[8]=[101](e)
enc_str2[10]=[108](l)
enc_str2[12]=[-61](▒)
enc_str2[14]=[-82](▒)
enc_str2[16]=[99](c)
enc_str2[18]=[107](k)
Unicode 1: 0x7ffffeb27ff0
Unicode 2: 0x7ffffeb27fc0
Strings are equal
如果字符串不相等,则认为它们相等。我错过了什么
谢谢
us1
和us2
的长度都是1,它们的第一个字符分别是enc_str1
和enc_str2
。这可能就是字符串被视为相等的原因。我正在研究如何正确分配UnicodeString对象。如果使用“转换”字符串enc_str1
和enc_str2
初始化UnicodeString
,则UnicodeString的长度为1。如果使用str1
和str2
对其进行初始化,则us1
和us2
的长度为8。可能是enc_str1
和enc_str2
中第一个字符t
的第二个字节中的0(NULL)导致UnicodeString将其视为字符串的结尾?我需要一种方法将enc_str1
和enc_str2
转换为UnicodeString对象,以便ICU将其视为UTF16字符串。再三考虑,在对象构造期间,UnicodeString
不会将str1
和str2
转换为UTF16吗?很抱歉有这么多评论,但我会在这些想法出现时发布它们。
$ ./a.out
Local encoding:
ISO_8859-1
String1:
tägelîch
String2:
tägelîck
enc_str1[0]=[116](t)
enc_str1[2]=[-61](▒)
enc_str1[4]=[-92](▒)
enc_str1[6]=[103](g)
enc_str1[8]=[101](e)
enc_str1[10]=[108](l)
enc_str1[12]=[-61](▒)
enc_str1[14]=[-82](▒)
enc_str1[16]=[99](c)
enc_str1[18]=[104](h)
enc_str2[0]=[116](t)
enc_str2[2]=[-61](▒)
enc_str2[4]=[-92](▒)
enc_str2[6]=[103](g)
enc_str2[8]=[101](e)
enc_str2[10]=[108](l)
enc_str2[12]=[-61](▒)
enc_str2[14]=[-82](▒)
enc_str2[16]=[99](c)
enc_str2[18]=[107](k)
Unicode 1: 0x7ffffeb27ff0
Unicode 2: 0x7ffffeb27fc0
Strings are equal