SANE(R)在Mac OS X中获取CLI的字符编码的方法?
-
28-09-2019 - |
题
我正在为Mac OS X(10.5+)编写一个CLI-Tool,该工具必须处理很可能包含非ASCII字符的命令行参数。
为了进一步处理,我使用 +[NSString StringWithCstring:编码:]转换这些参数。
我的问题是,我找不到有关如何确定所述Cli-Tool正在运行的外壳使用的字符编码的好信息。
我想出的解决方案是以下内容:
NSDictionary *environment = [[NSProcessInfo processInfo] environment];
NSString *ianaName = [[environment objectForKey:@"LANG"] pathExtension];
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(
CFStringConvertIANACharSetNameToEncoding( (CFStringRef)ianaName ) );
NSString *someArgument = [NSString stringWithCString:argv[someIndex] encoding:encoding];
但是,我发现有点粗糙 - 这让我认为我错过了一些明显的东西……但是呢?
是否有一种更清洁的方法可以实现基本相同的方法?
提前致谢
d
解决方案 3
好的,事实证明似乎没有!
正如Yuji指出的那样,无论如何,文件名的基本编码都是UTF-8。因此,需要处理 两种情况:
- 用户键入字符的参数,字符。
- 选项卡的参数或命令的输出
ls
, ,因为它们不会转换任何字符。
第二种情况仅由UTF-8的假设涵盖。
但是,第一种情况是有问题的:
- 在Mac OS 10.6上,$ lang包含所用编码的IANA名称
de_DE.IANA_NAME
. - 在雪豹之前, 不是这种情况 为了 除UTF-8以外的其他charsets!
我没有测试我能想到的每一个炭?相反,$ lang仅是语言透明化(de_DE
就我而言)!
自呼叫的结果 +[NSString stringWithCString:encoding:]
编码不正确 不确定, ,您不能安全地假设它将返回 nil
在这种情况下*(例如,仅限ASCII,它可能会很好地工作!)。
加上整体混乱的是 $LANG
没有固定 无论如何,要解决:terminal.app的首选项中有一个复选框,使用户无法设置 $LANG
根本没有说明X11.App似乎无法处理任何非ASCII输入...)。
那还剩下什么:
- 检查是否存在
$LANG
. 。如果没有设置,请goto:4! - 检查是否
$LANG
包含有关编码的信息。如果没有,goto:4! - 检查编码是否发现有UTF-8。如果是goto:6,否则...
- 如果
argc
大于2,[[NSString stringWithCString: argv[0] encoding: NSUTF8StringEncoding] isEqualToString: yourForceUTFArgumentFlag]
, ,打印您现在强迫UTF-8和Goto 6.如果不是: - 假设您一无所知,发出警告,您的用户应将终端编码设置为UTF-8,并可能考虑通过
yourForceUTFArgumentFlag
作为第一个论点, 出口(). - 假设UTF-8并做您必须做的...
听起来很糟糕?那是因为是,但我想不出 疗养院 这样做的方式。
不过另一个注释:如果您将UTF-8用作编码,则字符串WithCstring:编码:每当遇到C-String中的非ASCII字符时返回nil 不是 在UTF-8中编码。)
其他提示
答案取决于非伴奏的来源。
- 在OS X中,环境变量
LANG
做 不是 反映GUI中语言的选择。很少有人会LANG
在命令行。 - GUI处的“系统编码”的选择存储在
~/.CFUserTextEncoding
, ,可以通过CFStringGetSystemEncoding
, ,看到这个 苹果文档. - 也就是说,这个“编码系统”是 几乎没有使用过 除了一个非常古老的非固定模具软件。任何理智的可可计划都只使用Unicode,而别无其他。
特别是,Cocoa级别的文件路径始终在UTF-8的(一个变体)中编码。所以,要获得
NSString
从C字符串,使用NSString*string=[NSString stirngWithCString:cString encoding:NSUTF8Encoding];
并从一个从一个文件路径中获得C弦
NSString
, , 采用char*path=[string fileSystemRepresentation];
在这里建议不要仅使用
[string UTF8String]
, ,由于微妙,请参阅 苹果文档.因此,我建议您不要关心编码,只是假设UTF-8。
- 也就是说,可能有很少的人
LANG
在命令行上,您可能想照顾它们。然后,您所做的是我唯一想出的事情。
你不能只使用 [[NSProcessInfo processInfo] arguments]
?