提问人:Dave Coventry 提问时间:5/14/2023 最后编辑:Dave Coventry 更新时间:5/19/2023 访问量:101
我的 C 程序如何将字符串插入到包含字符> 0x80的 mariadb 数据库中
How does my C program insert a string into a mariadb database which contains a character > 0x80
问:
我的 C 程序尝试将字符串插入 Mariadb 数据库:
sprintf(query,"INSERT INTO text(drawing, eID, txt) VALUES(%s,%ld,'%s');",drawing_number,element_handle,txt);
mysql_query(sqlconnect,query);
如果 txt 字符串不包含字符 > 127,则它可以正常工作。
但是,如果字符串包含度数字符,例如(°,0xB0),则据我所知,该字符串不会插入到数据库中,而不会出现任何错误。
GDB 显示已正确提交字符串的查询,但未包含以下字符:
(GDB) P 查询
$7 = 0x5555555a1dd0 “INSERT INTO text(drawing, eID, txt) VALUES(6,1000699,'FOR DETAILS OF');”
但是对于包含度数字符的字符串,这是 GDB 向我展示的:
(GDB) P 查询
$8 = 0x5555555a1dd0 “INSERT INTO text(drawing, eID, txt) VALUES(6,1000700,'SUCTION BOX 22\260');”
如果我使用“”或“”搜索数据库,它将返回一个空集。select * from text where drawing=6 and txt like 'SUCTION BOX%';
select * from text where drawing=6 and eID=1000700;
数据库架构为“utf8mb3”。
显然,字符串的编码不正确,那么如何确保它编码正确?
这不可能是一个独特的问题,但我似乎找不到解决方案(很可能我使用了糟糕的搜索字符串),所以我希望你能原谅重复。
建议的解决方案似乎是使用 C 查询具有 unicode 字符的数据库。据我所知,该行实际上并没有首先插入到数据库中。我可以手动插入行:。INSERT INTO text(drawing, eID, txt) VALUES(6,1000700,'SUCTION BOX 22�');
它显然不是由我的编译器编码的。gcc 版本 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04)。
我的研究表明,默认情况下,char 数据类型会自动指定为 utf8。我假设是这样吗?
原始文本采用固定的宽字符格式,即两个字节,最低有效字节在前。不过,我不认为这是一种正常的 wc 格式,因为我尝试使用 wctombs() 失败了。
答:
该问题是导致 utf-8 字符数组被错误分配。
我创建了一个 wchar_t 数组,并用原始数组填充它(它由 2 个字节组成,最低有效字节在前)。
for(int i=0;i<sz;i++){
ut[i]=(s[ii++])&0xFF;
ut[i]+=((s[ii]&0xFF)<<8);
ut[i]&=0xFFFF;
ii++;
if(!ut[i])
break;
}
然后,我将新创建的数组转换为字符。wctombs
char *rt;
rt=(char *)malloc(sz*2);
wcstombs(rt,ut,sz);
return rt;
这奏效了。
我不知道为什么,但是原始数组的格式与转换工具不兼容。
我相信有更好的方法,并且会坦率地承认我的编码非常笨拙,但我想结束这个问题。
非常感谢所有回复的人。
评论
sprintf()