以下是添加了详细中文注释的代码版本,解释每一行代码的作用:
cpp
#include <CoreFoundation/CoreFoundation.h>
#include <vector>
#include <string>
#include <iostream>
// 将 Core Foundation 的字符串(CFStringRef)转换为标准 C++ 字符串(std::string)
std::string CFStringToStdString(CFStringRef cfStr) {
// 检查传入的 CFStringRef 是否为空
if (!cfStr) return "";
// 获取 CFString 的长度(字符数)
CFIndex length = CFStringGetLength(cfStr);
// 计算转换为 UTF-8 编码后可能需要的最大字节数,+1 是为了字符串结束符'\0'
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
// 分配足够大的缓冲区
char* buffer = new char[maxSize];
// 尝试将 CFString 转换为 C 风格字符串(UTF-8编码)
if (CFStringGetCString(cfStr, buffer, maxSize, kCFStringEncodingUTF8)) {
// 转换成功,创建 std::string
std::string result(buffer);
// 释放缓冲区
delete[] buffer;
return result;
}
// 转换失败,释放缓冲区并返回空字符串
delete[] buffer;
return "";
}
// 获取系统支持的所有地区标识符
std::vector<std::string> GetAllSystemLocaleIDs() {
// 创建存储结果的向量
std::vector<std::string> locales;
// 调用 Core Foundation 函数获取所有可用的地区标识符
// 返回的是一个 CFArrayRef,包含所有地区ID
CFArrayRef localeIDs = CFLocaleCopyAvailableLocaleIdentifiers();
// 检查是否获取成功
if (!localeIDs) return locales;
// 获取数组中的元素数量
CFIndex count = CFArrayGetCount(localeIDs);
// 遍历数组中的每个元素
for (CFIndex i = 0; i < count; i++) {
// 获取数组中第i个元素(CFStringRef类型)
CFStringRef localeID = (CFStringRef)CFArrayGetValueAtIndex(localeIDs, i);
// 转换为 std::string
std::string localeStr = CFStringToStdString(localeID);
// 如果转换成功且非空,添加到结果向量中
if (!localeStr.empty()) {
locales.push_back(localeStr);
}
}
// 释放 Core Foundation 数组对象
CFRelease(localeIDs);
return locales;
}
// 获取当前系统的地区设置
std::string GetCurrentLocaleID() {
// 获取当前地区设置(返回的对象需要手动释放)
CFLocaleRef locale = CFLocaleCopyCurrent();
// 从地区对象中获取标识符字符串
CFStringRef localeID = CFLocaleGetIdentifier(locale);
// 转换为 std::string
std::string result = CFStringToStdString(localeID);
// 释放地区对象
CFRelease(locale);
// 返回地区标识符字符串,如 "zh_CN" 或 "en_US"
return result;
}
int main() {
// 获取所有系统支持的地区标识符
auto allLocales = GetAllSystemLocaleIDs();
// 打印支持的地区总数
std::cout << "系统支持的地区数量 (" << allLocales.size() << "):\n";
// 遍历并打印每个地区标识符
for (const auto& locale : allLocales) {
std::cout << locale << "\n";
}
// 获取并打印当前地区设置
auto local_name = GetCurrentLocaleID();
std::cout << "当前地区设置: " << local_name << std::endl;
return 0;
}
关键点说明:
-
内存管理:
• Core Foundation 对象(如 CFArrayRef、CFStringRef)需要手动管理内存
• 使用
CFRelease()
释放通过 Copy/Create 规则获得的对象 -
类型转换:
•
CFStringRef
是 Core Foundation 的字符串类型• 需要转换为
std::string
才能在 C++ 中方便使用 -
API 功能:
•
CFLocaleCopyAvailableLocaleIdentifiers()
获取系统支持的所有地区•
CFLocaleCopyCurrent()
获取用户当前设置的地区 -
编码处理:
• 使用 UTF-8 编码处理多语言字符串
• 考虑了字符串转换失败的情况
这个代码完整展示了如何在 macOS 系统中获取地区信息,并正确处理内存管理和类型转换。