从指针到char返回正确的变音字符?

时间:2014-10-22 06:28:53

标签: c r pointers utf-8 char

我正在尝试从传统的FAME数据库文件中获取正确的字符描述。基本上这是有效的,但是变音符号等打印不正确。基本上,R Package FAME中包含的以下C函数是一个C问题而不是R问题。

void fameWhat(int *status, int *dbkey, char **objnam, int *class,
         int *type, int *freq, int *basis, int *observ,
         int *fyear, int *fprd, int *lyear, int *lprd, 
         int *obs, int *range, 
         int * getdoc, char **desPtr, char **docPtr){
 /* Get info about an object. Note that range should be an int[3] on input */
int cyear, cmonth, cday, myear, mmonth, mday;
int i;
char fdes[256], fdoc[256];

if(*getdoc){
if(strlen(*desPtr) < 256 || strlen(*docPtr) < 256){
  *status = HBNCHR;
  return;
}
for(i = 0; i < 255; ++i) fdes[i] = fdoc[i] = ' ';
}
fdes[255] = fdoc[255] =  '\0';

cfmwhat(status, *dbkey, *objnam, class, type, freq, basis, observ,
      fyear, fprd, lyear, lprd, &cyear, &cmonth, &cday, &myear,
      &mmonth, &mday, fdes, fdoc);
if(*getdoc){
  strncpy(*desPtr, fdes, 256);
  strncpy(*docPtr, fdoc, 256);
}
if(*status == 0 && *class == HSERIE)
  cfmsrng(status, *freq, fyear, fprd, lyear, lprd, range, obs);
return;
}

我觉得由于指向描述的指针desPtr的指针属于char类型的事实,当从R调用此函数并显示结果时,我没有得到任何正确的变音符号在R控制台内。我有一种预感,即FAME是Latin-1编码的。 R是UTF-8。对于ä,我得到\U3e34653c

那么有没有办法在C中完成它并将正确的值传递给R或者我应该在R中搜索和替换?

注意:我看过这个帖子Using Unicode in C++ source codeHow to use utf8 character arrays in c++?

1 个答案:

答案 0 :(得分:1)

看起来你有一些多堆叠编码/解码。你是怎么得到的?&#39;首先是单个字符的长Unicode值?

该长代码的原始十六进制到ASCII转换是>4E<<E4>(取决于字节顺序),后者被解释为括号内的十六进制值,是{{1你期待的是:http://www.fileformat.info/info/unicode/char/00E4/index.htm,这是一种有效的Latin-1编码。

从这种编码格式转换为UTF8相对简单,虽然我不确定将此代码粘贴到现有例程中的位置。作为独立程序示例:

ä

这将扫描输入字符串#include <stdio.h> #include <stdlib.h> int main (void) { char input[] = "a sm<F6>rg<E5>sbord of <code>"; char *sourceptr, *destptr, *endptr; int latin1; sourceptr = input; destptr = input; while (*sourceptr) { if (*sourceptr == '<') { latin1 = strtol (sourceptr+1, &endptr, 16); if (endptr && *endptr == '>' && latin1 > 127 && latin1 <= 255) { /* printf ("we saw hex code %xh\n", latin1); */ /* Quick-and-dirty converting to UTF8: */ *destptr = (char)(0xc0 | ((latin1 & 0xc0) >> 6)); destptr++; *destptr = (char)(0x80 | (latin1 & 0x3f)); destptr++; sourceptr = endptr+1; continue; } } *destptr = *sourceptr; sourceptr++; destptr++; } *destptr = 0; printf ("output: %s\n", input); return 0; } 后跟一个有效的十六进制代码(假设它是拉丁语-1,因此它被限制为80..FF)和另一个{{1} }。找到后,它会以UTF8格式插入字符。无法识别的序列按原样复制。