我正在制作支持多种语言的C程序。程序使用WCHAR类型而不是char发送电子邮件。问题是,当我收到电子邮件并阅读它时,某些字符显示不正确,甚至一些英文字符如e,m,...这是一个例子:
<!-- language: lang-c -->
curl_easy_setopt(hnd, CURLOPT_READFUNCTION, payload_source);
curl_easy_setopt(hnd, CURLOPT_READDATA, &upload_ctx);
static const WCHAR *payload_text[]={
L"To: <me@mail.com>\n",
L"From: <me@mail.com>(Example User)\n",
L"Subject: Hello!\n",
L"\n",
L"Message sent\n",
NULL
};
struct upload_status {
int lines_read;
};
static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp){
struct upload_status *upload_ctx = (struct upload_status *)userp;
const WCHAR *data;
if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
if (data) {
size_t len = wcslen(data);
memcpy(ptr, data, len);
upload_ctx->lines_read ++;
return len;
}
return 0;
}
答案 0 :(得分:0)
memcpy()
对字节进行操作,而不对字符进行操作。您没有考虑sizeof(wchar_t) > 1
。某些系统上有2个字节,其他系统上有4个字节。在编写可移植代码时,这种不确定性使wchar_t
成为一个糟糕的选择。您应该使用Unicode库,例如icu或iconv)。
调用sizeof(wchar_t)
时,您需要考虑memcpy()
。您还需要考虑目标缓冲区可能小于您尝试复制的文本字节的大小。单独跟踪lines_read
是不够的,您还必须跟踪当前行复制的字节数,以便在当前文本行跨越多个目标缓冲区时处理案例。 / p>
尝试更像这样的东西:
static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *) userp;
unsigned char *buf = (unsignd char *) ptr;
size_t available = (size * nmemb);
size_t total = 0;
while (available > 0)
{
wchar_t *data = payload_text[upload_ctx->lines_read];
if (!data) break;
unsigned char *rawdata = (unsigned char *) data;
size_t remaining = (wcslen(data) * sizeof(wchar_t)) - upload_ctx->line_bytes_read;
while ((remaining > 0) && (available > 0))
{
size_t bytes_to_copy = min(remaining, available);
memcpy(buf, rawdata, bytes_to_copy);
buf += bytes_to_copy;
available -= bytes_to_copy;
total = bytes_to_copy;
rawdata += bytes_to_copy;
remaining -= bytes_to_copy;
upload_ctx->line_bytes_read += bytes_to_copy;
}
if (remaining < 1)
{
upload_ctx->lines_read ++;
upload_ctx->line_bytes_read = 0;
}
}
return total;
}