我正在尝试使用ICU的比较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.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;
}
输出:
$ ./a.out
Local encoding:
ISO_8859-1
String1:
tägelîch
String2:
tägelîch
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]=[104](h)
Unicode 1: 0x7ffffacd0e50
Unicode 2: 0x7ffffacd0e20
Strings are equal
有趣的是,即使输入字符串相同,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
当它们不是时,它们被视为相等。我错过了什么?
谢谢!