对于一个小项目,我需要在 Windows 的 CMD 中输出可能已本地化的文本字符串,并从程序的参数中读取一些字符串。为了简化问题,我将使用一个简单的 echo 程序作为演示。
请考虑 C 语言的片段:
#include <stdio.h>
int main(int argc, char **argv) {
// Display the first argument through the standard output:
if (argc > 1)
puts(argv[1]);
return 0;
}
这些是两次执行的输出:
$ test.exe Wilhelm
$ Wilhelm
$ test.exe Röntgen
$ R÷ntgen
您已经可以看到,像 ö 这样的 ASCII 格式的内容将无法正确显示。但是它们在程序中被正确识别,例如,如果您执行以下操作:
if (argv[1][1] == 'ö')
puts("It is.");
将显示句子,因此程序正确接收字符。
所以我认为,好的,可能需要 wchar_t 东西,所以进行适当的更改并定义 UNICODE 和 _UNICODE 你会得到:
#include <stdio.h>
int wmain(int argc, wchar_t **argv) {
// Display the first argument through the standard output:
if (argc > 1)
_putws(argv[1]);
return 0;
}
这个测试程序的输出仍然是一样的。
环顾四周并阅读文档,我发现了一些解决方法,例如将语言环境设置为英语:然后文本将正确显示。修改第一个版本(没有 wchar_ts)我最终得到了这个:
#include <stdio.h>
#include <locale.h>
int main(int argc, char **argv) {
// Get the previous locale and change to English:
char *old_locale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "English");
// Display the first argument through the standard output:
if (argc > 1)
puts(argv[1]);
// Restore locale:
setlocale(LC_ALL, old_locale);
return 0;
}
("en-US" 似乎不能在 MinGW-w64 中工作,而 "English" 可以在它和 Microsoft Visual C++ 中工作)
现在程序可以打印了,这样字符就可以在命令行窗口中正确显示了。
问题是,在西类牙语系统或日语系统中,将内容设置为英语并不是最好的做法。所以我想通过某种方式从系统中获取语言环境。我找到了一个名为 _get_current_locale 的函数,它返回一个 _locale_t,但它似乎根本不是我想要的:
_locale_t_variable->locinfo->lc_category[LC_ALL].locale(这是一个 char *)似乎是 NULL。
那么问题来了,如何获取或显示命令行语言环境中的文本呢?在 Windows 的 CMD(不一定是 Unicode)中处理本地化文本的正确方法是什么?
最佳答案
“这是两个输出...”:如果您使用的是 cmd.exe,为什么提示符类似于美元符号?你是这样设置的吗?如果您确实在使用 cmd.exe,您可以检查“代码页”:
mode con cp /status
如果您发现它是 437,则可以解释您意外的观察结果。打开charmap.exe,你会发现你关心的字符叫做“U+00F6 Latin Small Letter O With Diaresis”。如果您使用代码页 437 将其粘贴到 CLI 中,则会发生一些有趣的事情...
将传递给 unicode 程序的代码将是:0xF6,0x00您的程序将收到此代码。
该字符被识别为存在于代码页 437 中,但代码为 0x94。我相信 CLI(包括 echo 命令)会执行一些所见即所得的操作,后一个代码 (0x94) 会显示给您并输出到 stdout。
如果您从 CLI 将该字符复制到剪贴板,它将获得与“OEM 文本”和 0x94 代码的额外关联。
现在让我们切换到代码页1252:
mode con cp select=1252
在此代码页中,当您从Character Map 粘贴到 CLI 时,传递给 unicode 程序的代码与之前的场景相同。
但现在您观察到的字符是 Terminal 字体(视觉上类似于代码页 437 的字体)中的 0xF6,因此您有除号。 echo 命令会将相同的代码发送到 stdout。
如果您从 CLI 将该字符复制到剪贴板,它将获得与“OEM 文本”和 0x94 代码的额外关联,与之前相同。
如果您将带有此字符的 echo 命令的输出重定向到一个文件,并使用终端字体在 记事本 中打开一个文件,您将看到除法-符号。如果将字体更改为 Courier New,您将看到符合 Unicode 的“带有分音符的小 o”。
现在切换回代码页437:
mode con cp select=437
如果你想让 Windows unicode 程序将未翻译的 Unicode 序列输出到 FILE *,我相信你必须使用 binary 模式。要修改您的原始代码,您可能需要:
#define _UNICODE
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <fcntl.h>
#include <io.h>
int __cdecl _tmain(int argc, TCHAR ** argv, TCHAR ** envp) {
wchar_t bom = 0xFEFF;
_setmode(_fileno(stdout), _O_BINARY);
_ftprintf(stdout, _T("%c"), bom);
_putts(argv[1]);
return EXIT_SUCCESS;
}
在这个例子中,我们在写入 UTF-16 字符之前先写入 UTF-16LE 字节顺序标记(“BOM”) stdout 的参数。这在 CLI 中看起来很难看,但如果您重定向到一个文件或直接使用一个文件(以二进制模式),结果可能更符合您最初感兴趣的内容:
#define _UNICODE
#ifdef _UNICODE
#define BOM { 0xFF, 0xFE, 0, 0 }
#else
#define BOM { 0 }
#endif
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <fcntl.h>
#include <io.h>
int __cdecl _tmain(int argc, TCHAR ** argv, TCHAR ** envp) {
/* Initialize the BOM string */
static const union {
unsigned char bytes[sizeof (TCHAR) * 2];
TCHAR c[2];
} bom = BOM;
FILE * f;
TCHAR filename[] = _T("testfile.txt");
int r;
int rc;
/* Assume failure */
rc = EXIT_FAILURE;
if (argc != 2) {
_ftprintf(stderr, _T("Usage: %s <word>\n"), argv[0]);
goto err_usage;
}
f = _tfopen(filename, _T("wb"));
if (!f) {
_ftprintf(stderr, _T("Could not open file: %s\n"), filename);
goto err_fopen;
}
r = _ftprintf(f, _T("%s"), bom.c);
if (r != _tcsclen(bom.c)) {
_ftprintf(stderr, _T("Could not write BOM to file\n"));
goto err_bom;
}
r = _ftprintf(f, _T("%s"), argv[1]);
if (r != _tcsclen(argv[1])) {
_ftprintf(stderr, _T("Could not write argument to file\n"));
goto err_arg;
}
rc = EXIT_SUCCESS;
err_arg:
err_bom:
fclose(f);
err_fopen:
err_usage:
return rc;
}
以下是一些可能有帮助的额外资源:
_tfopen:http://msdn.microsoft.com/en-us/library/yeby3zcb.aspx
_ftprintf:http://msdn.microsoft.com/en-us/library/xkh07fe2.aspx
_setmode:http://msdn.microsoft.com/en-us/library/tw4k6df8.aspx
关于文本和二进制流的 Unicode:http://msdn.microsoft.com/en-us/library/c4cy2b8e.aspx
SBCS、MBCS、Unicode 函数:http://msdn.microsoft.com/en-us/library/tsbaswba.aspx
关于c - 如何在命令行的语言环境中显示文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23727211/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende