以下可能不符合 SO 问题;如果超出范围,请随时告诉我离开。这里的问题基本上是,“我是否正确理解了 C 标准,这是正确的处理方式吗?”
我想就我对 C(以及 C++ 和 C++0x)中的字符处理的理解要求澄清、确认和更正。首先,一个重要的观察:
可移植性和序列化是正交的概念。
便携的东西是像 C 一样的东西,unsigned int , wchar_t .可序列化的东西是类似 uint32_t 的东西或 UTF-8。 “可移植”意味着您可以重新编译相同的源代码并在每个受支持的平台上获得工作结果,但二进制表示可能完全不同(或者甚至不存在,例如 TCP-over-carrier pig)。另一方面,可序列化的事物总是具有相同的表示,例如我可以在 Windows 桌面、手机或牙刷上阅读的 PNG 文件。可移植的东西是内部的、可序列化的东西,处理 I/O。可移植的东西是类型安全的,可序列化的东西需要类型双关。
当谈到 C 中的字符处理时,有两组分别与可移植性和序列化相关的事情:
wchar_t , setlocale() , mbsrtowcs()/wcsrtombs() : C 标准没有提及“编码” ;事实上,它与任何文本或编码属性完全无关。它只说“你的入口点是 main(int, char**);你得到一个类型 wchar_t,它可以保存你系统的所有字符;你得到函数来读取输入字符序列并将它们变成可用的 wstrings,反之亦然。iconv()和 UTF-8,16,32:一个函数/库,用于在定义明确的、明确的、固定的编码之间进行转码。 iconv 处理的所有编码都得到普遍理解和认可,只有一个异常(exception)。 wchar_t 之间的桥梁可移植字符类型和确定性的外部世界是 WCHAR-T 和 UTF 之间的 iconv 转换。wcsrtombs() 与 CRT 接口(interface),并使用 iconv()序列化?从概念上讲: my program
<-- wcstombs --- /==============\ --- iconv(UTF8, WCHAR_T) -->
CRT | wchar_t[] | <Disk>
--- mbstowcs --> \==============/ <-- iconv(WCHAR_T, UTF8) ---
|
+-- iconv(WCHAR_T, UCS-4) --+
|
... <--- (adv. Unicode malarkey) ----- libicu ---+
// Portable wmain()-wrapper
#include <clocale>
#include <cwchar>
#include <string>
#include <vector>
std::vector<std::wstring> parse(int argc, char * argv[]); // use mbsrtowcs etc
int wmain(const std::vector<std::wstring> args); // user starts here
#if defined(_WIN32) || defined(WIN32)
#include <windows.h>
extern "C" int main()
{
setlocale(LC_CTYPE, "");
int argc;
wchar_t * const * const argv = CommandLineToArgvW(GetCommandLineW(), &argc);
return wmain(std::vector<std::wstring>(argv, argv + argc));
}
#else
extern "C" int main(int argc, char * argv[])
{
setlocale(LC_CTYPE, "");
return wmain(parse(argc, argv));
}
#endif
// Serialization utilities
#include <iconv.h>
typedef std::basic_string<uint16_t> U16String;
typedef std::basic_string<uint32_t> U32String;
U16String toUTF16(std::wstring s);
U32String toUTF32(std::wstring s);
/* ... */
iconv -转换部分核心和使用uint32_t/char32_t -strings 在内部使用 UCS-4。 mbstowcs基本上没用(除了微不足道的扩大)。从 Explorer-drop 和 GetCommandLineW 接收宽字符串参数+ CommandLineToArgvW工作(也许应该有一个单独的 Windows 包装器)。 char16_t 不构成有效 UTF16(例如裸代理)的序列是有效的 NTFS 文件名),您必须小心。标准 C fopen无法打开所有 NTFS 文件,因为没有可能的转换映射到所有可能的 16 位字符串。使用 Windows 专用 _wfopen可能需要。作为推论,通常没有明确定义的“多少个字符”包含给定文件名的概念,因为首先没有“字符”的概念。买者自负。 最佳答案
Is this the right way to write an idiomatic, portable, universal, encoding-agnostic program core using only pure standard C/C++
wchar_t (不一定在内部,但在系统的所有接口(interface)上)。例如,如果您从int main(int argc, char** argv)
int wmain(int argc, wchar_t** argv)
GetCommandLineW函数,在 C 标准中没有指定。#ifdef s。 wchar_t是 Windows 上的 UTF-16 代码单元,char通常(bot 并不总是)Linux 上的 UTF-8 代码单元。编码意识通常是更理想的目标:确保您始终知道您使用哪种编码,或者使用将它们抽象出来的包装库。 关于c++ - WChars、编码、标准和可移植性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6300804/
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
我想使用spawn(针对多个并发子进程)在Ruby中执行一个外部进程,并将标准输出或标准错误收集到一个字符串中,其方式类似于使用Python的子进程Popen.communicate()可以完成的操作。我尝试将:out/:err重定向到一个新的StringIO对象,但这会生成一个ArgumentError,并且临时重新定义$stdxxx会混淆子进程的输出。 最佳答案 如果你不喜欢popen,这是我的方法:r,w=IO.pipepid=Process.spawn(command,:out=>w,:err=>[:child,:out])
我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功
查看Ruby代码,它具有以下proc_arity:staticVALUEproc_arity(VALUEself){intarity=rb_proc_arity(self);returnINT2FIX(arity);}更多的是C编码风格问题,但为什么staticVALUE在单独的一行而不是像这样的:staticVALUEproc_arity(VALUEself) 最佳答案 它来自UNIX世界,因为它有助于轻松grep函数的定义:$grep-n'^proc_arity'*.c或使用vim:/^proc_arity