我试图在MariaDB数据库中插入一个字符串,其中包含一个大于128的Unicode字符,即177,±
。
wchar_t wcs = L"INSERT INTO text(drawing, eID, txt) VALUES(9,14063,'\261\065\061\067\071')";
字符串
使用wctombs
:
int ret;
ret = wctombs(querybuffer, wcs, 60);
型ret
是-1,这显然意味着有一个宽字符不对应于有效的多字节字符。
我已经根据John Bollinger的建议修改了我的代码(非常感谢):
while(txt[i])
{
c=cleaveMControl(txt,&i,j);
if(c){
if(c<128)
query[j++]=c;
else{
query[j++]=92;
query[j++]=92;
sprintf(query+j,"u00%x",c);
j=strlen(query);
}
}
}
query[j++]=39;
query[j++]=41;
query[j++]=59;
query[j]=0;
mysql_query(sqlconnect,query);
型
这产生:
MariaDB [D8]> select * from text where eID=14063;
+---------+-------+------------+
| drawing | eID | txt |
+----------+-------+------------+
| 9 | 14063 | \u00b15179 |
+---------+-------+------------+
型
我期待看到“± 5179”。
1条答案
按热度按时间2j4z5cfb1#
如何确保在C程序中将包含uft 8字符的字符串正确写入mysql?
开始,这是错误的:
字符串
你的编译器应该警告你不要在没有强制转换的情况下将指针赋值给一个整数(而且是一个更窄的整数)。它也应该在这里抱怨:
型
..
wcs
的这种定义更有可能起作用:型
最主要的是,你需要声明
wcs
作为一个指针,而不是一个单独的wchar_t
。添加const
提供了一些保护,防止意外尝试修改内容,这是你不能做的。但如果你能假设至少是C11,那么
把这些放在一起,在C11或更高版本中,你可以说:
型
来获取所需的UTF-8编码字节,而无需考虑源和执行字符集。
顺便说一下,没有必要像我一样将其分为两个字面量,但这样做有助于澄清通用字符名称
\u00b1
不会继续到字符串的后续数字。(注意:也有8位通用字符名称,但它们以\U
而不是\u
开头)。如果你不能假设至少是C11,那么你最好还是跳过宽字符串字面量,而不是直接插入UTF-8编码的单个字符:
型
这确实依赖于对执行基本字符集的字符进行ASCII(和UTF8)兼容的编码,但这是一个相对安全的选择,并且与宽字符串变体工作所需的要求相比,这是一个较弱的要求。