问题
我有一个需求:压缩指定的文件夹,解压缩指定的压缩包到指定位置。
我尝试了 libarchive、zlib、libzip、libzippp,无一例外,如果路径中有中文字符,全部失败。要么压缩包中的中文乱码但内容完整,要么压缩包就是坏的。
解决
经这位网友提醒,对程序进行本地化设置后程序能够正确处理中文了。
关键部分:
CMakeLists.txt
if(WIN32)
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
endif()
解释:如果是 Windows 平台,且使用 MSVC 编译器,则添加 /utf-8
编译选项。作用:将源代码文件视为 UTF-8 编码,解决 MSVC 默认使用当前代码页的问题。
在程序的 main()
函数的开头添加:
main.cpp
解释:对程序进行 C 风格的本地化设置。由于 libarchive 是 C 库,所以使用std::setlocale()
进行本地化设置后 libarchive 就能使用 UTF-8 编码正确处理中文了。
如果是 C++ 程序还建议设置std::locale::global(std::locale(".UTF-8"));
,这是 C++ 风格的本地化设置,只会影响程序中 C++ 代码的字符处理方式。
完整代码
完整代码见: 使用libarchive将文件夹压缩为.tar.gz文件后再次解压,解决中文路径乱码问题
补充
std::setlocale()
基本语法
std::setlocale(
LC_ALL, // 类别参数
"en_US.UTF-8" // locale名称
);
类别参数选项:
LC_ALL // 设置所有类别
LC_COLLATE // 字符串比较和排序
LC_CTYPE // 字符分类和转换
LC_MONETARY // 货币格式化
LC_NUMERIC // 数字格式化
LC_TIME // 时间格式化
LC_MESSAGES // 系统消息
常见的locale名称格式:
".UTF-8" // UTF-8编码
"en_US.UTF-8" // 美式英语,UTF-8编码
"zh_CN.UTF-8" // 简体中文,UTF-8编码
"C" // 最小 C locale
"" // 使用系统默认locale
编写一个程序检查当前 locale
#include <iostream>
#include <clocale>
void printCurrentLocale() {
std::cout << "Current locale: "
<< std::setlocale(LC_ALL, nullptr)
<< std::endl;
}
int main() {
printCurrentLocale(); // 检查初始locale
std::setlocale(LC_ALL, "en_US.UTF-8");
printCurrentLocale(); // 检查设置后的locale
}
Current locale: C
Current locale: en_US.UTF-8
std::locale::global()
的使用效果
std::locale::global()
函数用于 C++ 风格的本地化设置(区域设置)。
例子:使用默认的区域设置输出一个数字,然后将全局区域设置更改为美国英语,并再次输出相同的数字。
32767
32,767