中文路径从ANSI格式转换成UTF-8格式后,无法识别

时间:2023-01-06 13:02:50
我的转换代码如下:
//ANSI 转换成 UTF-8(SQLITE数据库只能识别UTF-8的路径)

        char buf[1024];  //存放UFT-8的路径
{
//ANSI先转换成UNICODE
                CString strSQlitePathTmp = "E:\\美国\\0302--Polling Interval为4帧\\0302\\DB\\SQlite.db";
                wchar_t* wszString = new wchar_t[1024 + 1];
char szAnsi[1024];
strcpy(szAnsi, strSQlitePathTmp);
int wcsLen = ::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), NULL, 0); 
MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), wszString, wcsLen);
wszString[wcsLen] = '\0'; 

//UNICODE再转换成UTF-8 (放在buf里)
int u8Len = ::WideCharToMultiByte(CP_UTF8, NULL, wszString, wcslen(wszString), NULL, 0, NULL, NULL); 
WideCharToMultiByte(CP_UTF8, NULL, wszString, wcslen(wszString), buf, u8Len, NULL, NULL); 
buf[u8Len] = '\0'; 
}
        //此时 buf的保存的路径为 E:\缇庡浗\0302--Polling Interval涓?甯  0302\DB\SQlite.db,无法识别
  
        //但如果原路径中中文字符是连在一起,且是偶数的情况下,转换成UTF-8路径就可以识别

       兄弟姐妹们有什么好的方法啊,我已经被这个问题困扰好久了。谢谢大家了
       

30 个解决方案

#1


你转出来utf8的结果后,不能再当ansi参数传给其他函数。

#2



路径干吗要转呢?改用Unicode编码得了

#3


mark
哎,狗日的回复内容太短了!

#4


引用 1 楼 jennyvenus 的回复:
你转出来utf8的结果后,不能再当ansi参数传给其他函数。

因为这是VC中的路径,是ANSI格式的。而SQLITE数据库只能识别UTF-8格式,所以为了识别这个路径,必须转换啊。如果转换后的内容不能用,那如何解决这个问题呢?
谢谢

#5


引用 2 楼 visualeleven 的回复:
路径干吗要转呢?改用Unicode编码得了


必须转换啊,SQLITE数据库只能识别UTF-8格式。

#6


    正如我前面所说的,如果原路径中中文字符是连在一起,且是偶数的情况下,转换成UTF-8路径就可以识别。
    比如原路径为 "E:\美国\0302--Polling Interval4为帧\0302\DB\SQlite.db"(与之前的唯一区别是 为4帧 变成 4为帧),则转换成UTF-8格式的路径为"E:\缇庡浗\0302--Polling Interval4涓哄抚\0302\DB\SQlite.db",这种路径就可以识别了。 
    
    大家有什么好的建议啊

#7


谁说的,我的SQlite数据库就是用UNICODE方式的,切不管什么路径我都能打开

#8


引用 7 楼 zhou1xp 的回复:
谁说的,我的SQlite数据库就是用UNICODE方式的,切不管什么路径我都能打开


其实说到底是在VBA中,打开数据库时,找不到路径的问题。

    Dim ConnectionString As String
    Set conn = New Connection
    ConnectionString = "Driver={SQLite3 ODBC Driver};Database=" + strSQlitePath
    conn.ConnectionString = ConnectionString
    conn.Open  '中文路径会报错,必须转换成UTF-8格式的。

你有什么好的建议呢?

   

#9


你是什么工具,然后你的sqlite的lib文件是UNICODE方式生成还是ANSI方式下生成,还有你一定要用数据源方式打开么

#10


引用 9 楼 zhou1xp 的回复:
你是什么工具,然后你的sqlite的lib文件是UNICODE方式生成还是ANSI方式下生成,还有你一定要用数据源方式打开么

VC环境是VS2003,VBA环境是EXCEL2003。中间处理过程是在VC中生成一个数据库路径,然后调用VBA打开此Sqlite数据库及进行相关操作。

Sqlite的lib文件我使用 LIB /DEF:sqlite3.def /machine:IX86 命令生成,好像没有指定到底是什么格式的吧?应该属于默认的情况。 难道这里可以设定编码格式吗??

我现在只知道这个方法去打开数据库,有什么问题吗?

#11


呵呵,如果你是在VS2003下面自己编译生成的lib文件,那么你的sqlite数据库就是使用的UNICODE方式,现在你的VBA中好像是针对ANSI方式的

#12


引用 11 楼 zhou1xp 的回复:
呵呵,如果你是在VS2003下面自己编译生成的lib文件,那么你的sqlite数据库就是使用的UNICODE方式,现在你的VBA中好像是针对ANSI方式的


嗯这才是问题的纠结所在。 在VBA情况下,如何将ANSI格式的路径转换成UTF-8格式的呢?

#13


VBA调用我没用过,你在下面不能直接调用UNICODE方式么,要不你就把你的lib文件生成ANSI方式的就行了啊

#14


引用 13 楼 zhou1xp 的回复:
VBA调用我没用过,你在下面不能直接调用UNICODE方式么,要不你就把你的lib文件生成ANSI方式的就行了啊

如何生成ANSI格式的lib文件呢? 

#15


把预定义的UNICODE,_UNICODE改为_MBCS就行了,在你的工程设置仔细找一下

#16


注意是生成lib的工程设置,不过我建议你找一下VBA里面直接使用UNICODE的资料,这个更合理

#17


引用 15 楼 zhou1xp 的回复:
把预定义的UNICODE,_UNICODE改为_MBCS就行了,在你的工程设置仔细找一下


怎么跟VC工程扯上关系啦? 我是用 LIB /DEF:sqlite3.def /machine:IX86 命令生成LIB文件,应该是在这里设置格式吧?

#18


呵呵,楼主你去找点注明编译生成dll或者lib文件的资料看下吧,而且我敢肯定你没有看过sqlite3.h中的那些定义,def文件只是表示你的lib文件将导出那些函数而已

#19


是否是下面原因?

ASNI  转换前  一个中文 在内存中 占用 2 个字节, 每个字节被看为一个字符
转换 UNICODE  后, 一个中文占用的可能是4 个字节

#20


引用 19 楼 yzm888 的回复:
是否是下面原因?

 ASNI  转换前  一个中文 在内存中 占用 2 个字节, 每个字节被看为一个字符
 转换 UNICODE  后, 一个中文占用的可能是4 个字节

我需要的是UTF-8,一个中文字符占用3个字节。就因为这是奇数的,才造成无法识别的问题。

#21


引用 18 楼 zhou1xp 的回复:
呵呵,楼主你去找点注明编译生成dll或者lib文件的资料看下吧,而且我敢肯定你没有看过sqlite3.h中的那些定义,def文件只是表示你的lib文件将导出那些函数而已


sqlite3.h中的哪些定义??

#22


关于在VBA中对ANSI与UTF-8格式的处理,有没有一次资料可以参考呢? 网上搜索到的资料很少

#23


要想支持使用中文路径,要么工程使用UNICODE,然后打开SQLite使用UTF-16编码,如果不使用UNICODE,中文路径要用GB2312转UTF8,具体你到SQLite中文社区去搜吧,那里有办法
好久没用过SQLite了,具体也记不清怎么搞了。

#24


引用 23 楼 zxdlms 的回复:
要想支持使用中文路径,要么工程使用UNICODE,然后打开SQLite使用UTF-16编码,如果不使用UNICODE,中文路径要用GB2312转UTF8,具体你到SQLite中文社区去搜吧,那里有办法
 好久没用过SQLite了,具体也记不清怎么搞了。


现在问题的关键就是某些中文路径从GB2312转到UTF8后,无法识别的问题。 
比如,原路径为 E:\美国\SqliteDB.db,则转换为可以识别;  
   而原路径为E:\美\SQliteDB.db,转换后却无法识别。

#25


ANSI  美国   =  (4 ANSI字符 4字节)

转  UNICODE 后 美国  = (4个字符8字节)
UTF-8用1到6个字节编码UNICODE字符。

再转  UTF8,这种转换并不是把"美国"转换成 UTF-8, 而是把 4 个 ANSI转换成 UTF-8
------------------------------------------

一开始字符表示就要用UNICODE

wchar_t* wszString = _T("E:\\美国\\SqliteDB.db");
这种转换 UTF8应该是没有问题的,

所以,你的程序 UNICODE 表示的路径就是错误的




#26


变更 locale        

 locale loc = locale::global(locale(""));  // 保存之前locale, 并设置当前系统的locale
 ifstream IniFile(csFileName);    // csFileName 即使带unicode 也能识别
 locale::global(locale(loc));     // 恢复原来的locale

#27


引用 25 楼 yzm888 的回复:
ANSI  美国   =  (4 ANSI字符 4字节)

 转  UNICODE 后 美国  = (4个字符8字节)
 UTF-8用1到6个字节编码UNICODE字符。

 再转  UTF8,这种转换并不是把"美国"转换成 UTF-8, 而是把 4 个 ANSI转换成 UTF-8
 ------------------------------------------

 一开始字符表示就要用UNICODE

 wchar_t* wszString = _T("E:\\美国\\SqliteDB.db");
 这种转换 UTF8应该是没有问题的,

 所以,你的程序 UNICODE 表示的路径就是错误的


 wchar_t* wszString = _T("E:\\美国\\SqliteDB.db"); 转换成UTF8当然没问题。
但如果是 wchar_t* wszString = _T("E:\\美\\SqliteDB.db"); 这种路径转换就有问题了啊??

#28


引用 26 楼 byzantine2009 的回复:
变更 locale

  locale loc = locale::global(locale(""));  // 保存之前locale, 并设置当前系统的locale
  ifstream IniFile(csFileName);    // csFileName 即使带unicode 也能识别
  locale::global(locale(loc));     // 恢复原来的locale

我是要把路径传递给VBA进行处理,VBA是如何处理ASNI转换UTF8?

#29


但如果是 wchar_t* wszString = _T("E:\\美\\SqliteDB.db"); 这种路径转换就有问题了啊??
------------------------------
这种也没问题

但如果你一开始的路径是ANSI, 一个中文则是两个字符

两个ANSI字符转换为UNICODE还是两个字符,但正确是UNICODE是一个字符

#30


好比是这样

你有一块蛋糕("美"),要放盒子里, 但一个盒子太小, 只能分开放两个盒子里(分为了两块蛋糕)

ANSI 情况下, 实际上 "美" 被分为两个字符, 因为ANSI的盒子太小

转UNICODE时, 并不会知道原来的两块蛋糕 原先是由一块大蛋糕得来的, 所以还是两块蛋糕

#1


你转出来utf8的结果后,不能再当ansi参数传给其他函数。

#2



路径干吗要转呢?改用Unicode编码得了

#3


mark
哎,狗日的回复内容太短了!

#4


引用 1 楼 jennyvenus 的回复:
你转出来utf8的结果后,不能再当ansi参数传给其他函数。

因为这是VC中的路径,是ANSI格式的。而SQLITE数据库只能识别UTF-8格式,所以为了识别这个路径,必须转换啊。如果转换后的内容不能用,那如何解决这个问题呢?
谢谢

#5


引用 2 楼 visualeleven 的回复:
路径干吗要转呢?改用Unicode编码得了


必须转换啊,SQLITE数据库只能识别UTF-8格式。

#6


    正如我前面所说的,如果原路径中中文字符是连在一起,且是偶数的情况下,转换成UTF-8路径就可以识别。
    比如原路径为 "E:\美国\0302--Polling Interval4为帧\0302\DB\SQlite.db"(与之前的唯一区别是 为4帧 变成 4为帧),则转换成UTF-8格式的路径为"E:\缇庡浗\0302--Polling Interval4涓哄抚\0302\DB\SQlite.db",这种路径就可以识别了。 
    
    大家有什么好的建议啊

#7


谁说的,我的SQlite数据库就是用UNICODE方式的,切不管什么路径我都能打开

#8


引用 7 楼 zhou1xp 的回复:
谁说的,我的SQlite数据库就是用UNICODE方式的,切不管什么路径我都能打开


其实说到底是在VBA中,打开数据库时,找不到路径的问题。

    Dim ConnectionString As String
    Set conn = New Connection
    ConnectionString = "Driver={SQLite3 ODBC Driver};Database=" + strSQlitePath
    conn.ConnectionString = ConnectionString
    conn.Open  '中文路径会报错,必须转换成UTF-8格式的。

你有什么好的建议呢?

   

#9


你是什么工具,然后你的sqlite的lib文件是UNICODE方式生成还是ANSI方式下生成,还有你一定要用数据源方式打开么

#10


引用 9 楼 zhou1xp 的回复:
你是什么工具,然后你的sqlite的lib文件是UNICODE方式生成还是ANSI方式下生成,还有你一定要用数据源方式打开么

VC环境是VS2003,VBA环境是EXCEL2003。中间处理过程是在VC中生成一个数据库路径,然后调用VBA打开此Sqlite数据库及进行相关操作。

Sqlite的lib文件我使用 LIB /DEF:sqlite3.def /machine:IX86 命令生成,好像没有指定到底是什么格式的吧?应该属于默认的情况。 难道这里可以设定编码格式吗??

我现在只知道这个方法去打开数据库,有什么问题吗?

#11


呵呵,如果你是在VS2003下面自己编译生成的lib文件,那么你的sqlite数据库就是使用的UNICODE方式,现在你的VBA中好像是针对ANSI方式的

#12


引用 11 楼 zhou1xp 的回复:
呵呵,如果你是在VS2003下面自己编译生成的lib文件,那么你的sqlite数据库就是使用的UNICODE方式,现在你的VBA中好像是针对ANSI方式的


嗯这才是问题的纠结所在。 在VBA情况下,如何将ANSI格式的路径转换成UTF-8格式的呢?

#13


VBA调用我没用过,你在下面不能直接调用UNICODE方式么,要不你就把你的lib文件生成ANSI方式的就行了啊

#14


引用 13 楼 zhou1xp 的回复:
VBA调用我没用过,你在下面不能直接调用UNICODE方式么,要不你就把你的lib文件生成ANSI方式的就行了啊

如何生成ANSI格式的lib文件呢? 

#15


把预定义的UNICODE,_UNICODE改为_MBCS就行了,在你的工程设置仔细找一下

#16


注意是生成lib的工程设置,不过我建议你找一下VBA里面直接使用UNICODE的资料,这个更合理

#17


引用 15 楼 zhou1xp 的回复:
把预定义的UNICODE,_UNICODE改为_MBCS就行了,在你的工程设置仔细找一下


怎么跟VC工程扯上关系啦? 我是用 LIB /DEF:sqlite3.def /machine:IX86 命令生成LIB文件,应该是在这里设置格式吧?

#18


呵呵,楼主你去找点注明编译生成dll或者lib文件的资料看下吧,而且我敢肯定你没有看过sqlite3.h中的那些定义,def文件只是表示你的lib文件将导出那些函数而已

#19


是否是下面原因?

ASNI  转换前  一个中文 在内存中 占用 2 个字节, 每个字节被看为一个字符
转换 UNICODE  后, 一个中文占用的可能是4 个字节

#20


引用 19 楼 yzm888 的回复:
是否是下面原因?

 ASNI  转换前  一个中文 在内存中 占用 2 个字节, 每个字节被看为一个字符
 转换 UNICODE  后, 一个中文占用的可能是4 个字节

我需要的是UTF-8,一个中文字符占用3个字节。就因为这是奇数的,才造成无法识别的问题。

#21


引用 18 楼 zhou1xp 的回复:
呵呵,楼主你去找点注明编译生成dll或者lib文件的资料看下吧,而且我敢肯定你没有看过sqlite3.h中的那些定义,def文件只是表示你的lib文件将导出那些函数而已


sqlite3.h中的哪些定义??

#22


关于在VBA中对ANSI与UTF-8格式的处理,有没有一次资料可以参考呢? 网上搜索到的资料很少

#23


要想支持使用中文路径,要么工程使用UNICODE,然后打开SQLite使用UTF-16编码,如果不使用UNICODE,中文路径要用GB2312转UTF8,具体你到SQLite中文社区去搜吧,那里有办法
好久没用过SQLite了,具体也记不清怎么搞了。

#24


引用 23 楼 zxdlms 的回复:
要想支持使用中文路径,要么工程使用UNICODE,然后打开SQLite使用UTF-16编码,如果不使用UNICODE,中文路径要用GB2312转UTF8,具体你到SQLite中文社区去搜吧,那里有办法
 好久没用过SQLite了,具体也记不清怎么搞了。


现在问题的关键就是某些中文路径从GB2312转到UTF8后,无法识别的问题。 
比如,原路径为 E:\美国\SqliteDB.db,则转换为可以识别;  
   而原路径为E:\美\SQliteDB.db,转换后却无法识别。

#25


ANSI  美国   =  (4 ANSI字符 4字节)

转  UNICODE 后 美国  = (4个字符8字节)
UTF-8用1到6个字节编码UNICODE字符。

再转  UTF8,这种转换并不是把"美国"转换成 UTF-8, 而是把 4 个 ANSI转换成 UTF-8
------------------------------------------

一开始字符表示就要用UNICODE

wchar_t* wszString = _T("E:\\美国\\SqliteDB.db");
这种转换 UTF8应该是没有问题的,

所以,你的程序 UNICODE 表示的路径就是错误的




#26


变更 locale        

 locale loc = locale::global(locale(""));  // 保存之前locale, 并设置当前系统的locale
 ifstream IniFile(csFileName);    // csFileName 即使带unicode 也能识别
 locale::global(locale(loc));     // 恢复原来的locale

#27


引用 25 楼 yzm888 的回复:
ANSI  美国   =  (4 ANSI字符 4字节)

 转  UNICODE 后 美国  = (4个字符8字节)
 UTF-8用1到6个字节编码UNICODE字符。

 再转  UTF8,这种转换并不是把"美国"转换成 UTF-8, 而是把 4 个 ANSI转换成 UTF-8
 ------------------------------------------

 一开始字符表示就要用UNICODE

 wchar_t* wszString = _T("E:\\美国\\SqliteDB.db");
 这种转换 UTF8应该是没有问题的,

 所以,你的程序 UNICODE 表示的路径就是错误的


 wchar_t* wszString = _T("E:\\美国\\SqliteDB.db"); 转换成UTF8当然没问题。
但如果是 wchar_t* wszString = _T("E:\\美\\SqliteDB.db"); 这种路径转换就有问题了啊??

#28


引用 26 楼 byzantine2009 的回复:
变更 locale

  locale loc = locale::global(locale(""));  // 保存之前locale, 并设置当前系统的locale
  ifstream IniFile(csFileName);    // csFileName 即使带unicode 也能识别
  locale::global(locale(loc));     // 恢复原来的locale

我是要把路径传递给VBA进行处理,VBA是如何处理ASNI转换UTF8?

#29


但如果是 wchar_t* wszString = _T("E:\\美\\SqliteDB.db"); 这种路径转换就有问题了啊??
------------------------------
这种也没问题

但如果你一开始的路径是ANSI, 一个中文则是两个字符

两个ANSI字符转换为UNICODE还是两个字符,但正确是UNICODE是一个字符

#30


好比是这样

你有一块蛋糕("美"),要放盒子里, 但一个盒子太小, 只能分开放两个盒子里(分为了两块蛋糕)

ANSI 情况下, 实际上 "美" 被分为两个字符, 因为ANSI的盒子太小

转UNICODE时, 并不会知道原来的两块蛋糕 原先是由一块大蛋糕得来的, 所以还是两块蛋糕