- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
对于嵌入式软件项目,我正在添加对翻译的支持,并且由于我们运行的是嵌入式 Linux,所以我选择使用 libc gettext()
。我们没有安装任何语言环境定义,所以我只尝试将 LC_MESSAGES
语言环境设置为我想要的语言环境:
setlocale(LC_MESSAGES, "fake");
(在我得到正确的翻译之前,我使用名称 fake
和一个 fake.mo
文件来进行伪翻译)。
这在静态链接时工作正常,它返回一个语言环境句柄,bindtextdomain()
和 friend 都工作正常,我从中得到我的“翻译”字符串:
setlocale() returned "fake"
current textdomain is "ewe"
current base directory is "/opt/btech/probe/share/locale/WA"
current LC_MESSAGES locale is "fake"
gettext("Error") ==> "Ḗřřǿř"
现在,当我动态编译它时,它不起作用。既不在目标设备上,也不在我的 PC 本地(以相同方式安装文件)。 setlocale()
调用失败,返回一个 NULL
指针并将 errno 设置为 ENOENT
(未找到文件)。在 setlocale()
点,我没有将 bindtextdomain()
指向我的文件所在的位置,但切换调用也无济于事。
我是不是做错了,我上面的工作示例是不是错了,真的不应该工作?我是否需要为我调用 setlocale()
的任何内容定义语言环境,甚至是 LC_MESSAGES
?
这是测试二进制文件的来源:
#include <libintl.h>
#include <locale.h>
#include <stdio.h>
int main()
{
const char *l = setlocale(LC_MESSAGES, "fake");
printf("setlocale() returned \"%s\"\n", l);
bind_textdomain_codeset("ewe", "UTF-8");
bindtextdomain("ewe", "/opt/btech/probe/share/locale/WA");
textdomain("ewe");
printf("current textdomain is \"%s\"\n", textdomain(NULL));
printf("current base directory is \"%s\"\n", bindtextdomain(textdomain(NULL), NULL));
printf("current LC_MESSAGES locale is \"%s\"\n", setlocale(LC_MESSAGES, NULL));
printf("gettext(\"Error\") ==> \"%s\"\n", gettext("Error"));
return 0;
}
这是动态编译时的输出(针对目标或主机):
setlocale() returned "(null)"
current textdomain is "ewe"
current base directory is "/opt/btech/probe/share/locale/WA"
current LC_MESSAGES locale is "C"
gettext("Error") ==> "Error"
编辑:在我的主机 (x64 Linux) 上将测试二进制文件编译为静态也可以使它工作,因此静态编译有一些特殊之处。
附加问题:我可以强制 gettext 直接加载特定的 mo 文件吗?基本上我想用一个文件名参数代替 bindtextdomain()
。
编辑 2:所以,我最终找到了 this post说我可以让 gettext()
加载任何翻译,只要我先有一个有效的 setlocale()
调用。因此,我当前的解决方法是实际生成一个仅包含 en_US
语言环境的 /usr/lib/locale/locale-archive
,调用 setlocale(LC_MESSAGES, "en_US "); setenv("LANGUAGE", "fake");
,最终加载正确的消息目录。仍然感觉像是一个丑陋的解决方法,我仍然不明白为什么静态链接没有它就可以工作。
最佳答案
我有一个类似的问题(我对根文件系统没有太多控制的嵌入式系统),我发现这个解决方法有效:
/<mydir>/lang/
SYS_LC_MESSAGES
可以用 localedef
生成.我从系统上的 C 语言环境制作了一个并将其复制到每个目标目录
mkdir output
localedef -f UTF-8 -i /usr/share/i18n/locales/C output/mylocale
cp output/mylocale/LC_MESSAGES/SYS_LC_MESSAGES <mydir>/lang/ENG/LC_MESSAGES/
LOCPATH
至 <mydir>
strace
进行调试查看它正在尝试打开哪些文件。这是我最终的文件布局:
<mydir>
├── lang
│ ├── ENG
│ │ └── LC_MESSAGES
│ │ ├── SYS_LC_MESSAGES
│ │ └── mac.mo
│ ├── FRE
│ │ └── LC_MESSAGES
│ │ ├── SYS_LC_MESSAGES
│ │ └── mac.mo
│ ├── GER
│ │ └── LC_MESSAGES
│ │ ├── SYS_LC_MESSAGES
│ │ └── mac.mo
│ ├── ITA
│ │ └── LC_MESSAGES
│ │ ├── SYS_LC_MESSAGES
│ │ └── mac.mo
│ ├── SPA
│ │ └── LC_MESSAGES
│ │ ├── SYS_LC_MESSAGES
│ │ └── mac.mo
这是代码片段:
putenv("LOCPATH=/<mydir>/lang");
setlocale(LC_ALL, "");
setlocale(LC_MESSAGES, "ENG");
bindtextdomain("mac", "/<mydir>/lang");
textdomain("mac");
gettext("Hello world");
这是一个 hack,正确的解决方案是正确生成语言环境。
关于c - 将 LC_MESSAGES 设置为不存在的语言环境的 setlocale() 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36857863/
我想弄清楚 C++ 是如何支持 Unicode 的。 当我想将多语言文本输出到控制台时,我调用 std::setlocale .但是我注意到结果取决于之前对 setlocale 的调用. 考虑以下示例
如果我不使用fputws使用setlocale,则仅输出ASCII字母。似乎setlocale是必需的,并且根据this site,setlocale(LC_CTYPE, "UTF-8")和setlo
不允许在共享CentOS服务器上进行编译。因此,我在我的 Debian 计算机上编译我的程序,将其与 Debian 的系统库(如 libc 等)链接。然后我上传我的程序和 Debian 系统库,我的程
我需要为我的应用程序创建一个 SQLite 数据库。我需要用几种欧洲语言存储文本,因此会有大量重音字符和其他奇怪的标记。我正在扩展 SQLiteOpenHelper。 检查 .db 文件时,我注意到有
This paper说 setlocale() 是线程不安全的。是否有任何线程安全的方法来设置语言环境。 我正在用 C++ 编写代码,但如果有任何不同,C 库中的函数将使用语言环境。 这基本上就是我现
这个问题在这里已经有了答案: Is setlocale thread-safe function? (6 个答案) 关闭 6 年前。 CppRef states 2016-12-13 09:00 U
我编写了一个将 wstring 转换为字符串的函数。如果我删除代码 setlocale(LC_CTYPE, ""),程序就会出错。我引用了 cplusplus阅读文档。 C string contai
以下程序使用 setlocale() 从环境变量中获取区域设置,并打印时间。 locale_test.c: // locale test #include #include #include /
我正在学习 C++,我发现了 C++ 库的这个功能:setlocale ( http://www.cplusplus.com/reference/clocale/setlocale/ ) 但我无法理解
我有一个 Linux 系统,该系统设置为某个语言环境并运行一个 C++ 应用程序。我可以从 C++ 应用程序或操作系统本身执行 std::setlocale(LC_NUMERIC, "en_US.UT
我们目前面临的问题是,当使用 Windows 文件打开/保存对话框时加载的外部组件(不幸的是我们不知道是哪个)一些系统更改了进程的区域设置,可能是通过调用 setlocale(LC_ALL, "").
我需要更改线程中的区域设置以正确解析带有 strtod() 的 double ,为此我使用 setlocale() (C++)。它是线程安全的吗? 更新:另一个问题。当我在 main() 函数中调用
我有一些带有(瑞士)法语字符的字符串,我想大写(PHP 5.3)。 echo strtoupper('société'); 由于 strtoupper() 不适用于重字符,我做了一个 setlocal
根据 PHP,“语言环境信息由每个进程维护”。我的理解是否正确,这与使用 Apache 服务器的每个脚本实例相同? 换句话说,如果我有几个使用不同区域设置的并发 session ,一个用户区域设置的更
问题已解决(见下文) 我已经在我的服务器上生成了区域设置,我已经确认它们存在(我的区域设置 -a 在下面提供),但是当我使用时: setlocale(LC_TIME,'fr_FR');
我想在 php 中对包含德语“umlaute”的数组进行排序。这对于php来说似乎不是一件容易的事。我在网上找到了以下示例: $oldLocale=setlocale(LC_COLLATE, "0")
setlocale() 的默认设置是什么意思? setlocale()默认为“C”(“POSIX”)。但这到底是什么意思呢?它的默认字符集和语言是什么?是“en_US.utf8”吗? 最佳答案 来自
setlocale() 函数没有设置所需的语言(德语)。 目标是输出月份名称。 这是我到目前为止的测试代码:
JSTL 标签用于设置用户本地化环境。 语法 JSP 标签的语法如下: 其中: localcode:代表语言代码,例如,ZH、EN。也可以在后面加上国家或者地区的两位数代码,中间用_连接,如
#include #include #include "mainwindow.hpp" #include "../RegisterOfErrors.hpp" #include extern st
我是一名优秀的程序员,十分优秀!