我不清楚C中使用了什么编码argv
.特别是,我对以下场景感兴趣:
N
包含非ASCII字符的文件P在命令行上看到了什么字节序列?
我观察到在Linux上,在UTF-8语言环境中创建一个文件名然后在(例如)zw_TW.big5
语言环境中填充它似乎会导致我的程序P被输入UTF-8而不是Big5
.但是,在OS X上,同一系列操作会导致程序P获得Big5
编码的文件名.
这是我认为到目前为止所发生的事情(很长时间,我可能错了,需要纠正):
文件名以某种Unicode格式存储在磁盘上.所以Windows取名N
,从L1(当前代码页)转换为N
我们将调用的Unicode版本N1
,并存储N1
在磁盘上.
我接下来假设的是,当稍后完成制表符时,名称N1
将转换为区域设置L2(新的当前代码页)以供显示.幸运的是,这将产生原始名称N
- 但如果N
包含的字符在L2中无法代表,则不会成立.我们称之为新名称N2
.
当用户实际按Enter键以使用该参数运行P时,该名称N2
将转换回Unicode,N1
再次产生.这N1
是现在UCS2格式可供程序通过GetCommandLineW
/ wmain
/ tmain
,但用户GetCommandLine
/ main
会看到的名称N2
在当前区域设置(代码页).
据我所知,磁盘存储故事是一样的.OS X将文件名存储为Unicode.
使用Unicode终端,我认为终端会在Unicode缓冲区中构建命令行.因此,当选项卡完成时,它会将文件名作为Unicode文件名复制到该缓冲区.
当您运行该命令时,该Unicode缓冲区将转换为当前区域设置L2,并通过该方式提供给程序argv
,程序可以将具有当前区域设置的argv解码为Unicode以供显示.
在Linux上,一切都是不同的,我对正在发生的事情感到困惑.Linux将文件名存储为字节字符串,而不是Unicode.因此,如果您N
在区域设置L1中创建一个名称为file N
的字节字符串,则存储在磁盘上.
当我稍后运行终端并尝试选项卡完成名称时,我不确定会发生什么.在我看来,命令行被构造为字节缓冲区,并且作为字节字符串的文件名称只是连接到该缓冲区.我假设当你键入一个标准字符时,它会被动态编码为附加到该缓冲区的字节.
当你运行程序时,我认为缓冲区是直接发送的 …