我正在为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。因此,需要处理 两种情况:

  1. 用户键入字符的参数,字符。
  2. 选项卡的参数或命令的输出 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输入...)。

那还剩下什么:

  1. 检查是否存在 $LANG. 。如果没有设置,请goto:4!
  2. 检查是否 $LANG 包含有关编码的信息。如果没有,goto:4!
  3. 检查编码是否发现有UTF-8。如果是goto:6,否则...
  4. 如果 argc 大于2, [[NSString stringWithCString: argv[0] encoding: NSUTF8StringEncoding] isEqualToString: yourForceUTFArgumentFlag], ,打印您现在强迫UTF-8和Goto 6.如果不是:
  5. 假设您一无所知,发出警告,您的用户应将终端编码设置为UTF-8,并可能考虑通过 yourForceUTFArgumentFlag 作为第一个论点, 出口().
  6. 假设UTF-8并做您必须做的...

听起来很糟糕?那是因为是,但我想不出 疗养院 这样做的方式。


不过另一个注释:如果您将UTF-8用作编码,则字符串WithCstring:编码:每当遇到C-String中的非ASCII字符时返回nil 不是 在UTF-8中编码。)

其他提示

答案取决于非伴奏的来源。

  1. 在OS X中,环境变量 LANG不是 反映GUI中语言的选择。很少有人会 LANG 在命令行。
  2. GUI处的“系统编码”的选择存储在 ~/.CFUserTextEncoding, ,可以通过 CFStringGetSystemEncoding, ,看到这个 苹果文档.
  3. 也就是说,这个“编码系统”是 几乎没有使用过 除了一个非常古老的非固定模具软件。任何理智的可可计划都只使用Unicode,而别无其他。
  4. 特别是,Cocoa级别的文件路径始终在UTF-8的(一个变体)中编码。所以,要获得 NSString 从C字符串,使用

     NSString*string=[NSString stirngWithCString:cString encoding:NSUTF8Encoding];
    

    并从一个从一个文件路径中获得C弦 NSString, , 采用

     char*path=[string fileSystemRepresentation];
    

    在这里建议不要仅使用 [string UTF8String], ,由于微妙,请参阅 苹果文档.

  5. 因此,我建议您不要关心编码,只是假设UTF-8。

  6. 也就是说,可能有很少的人 LANG 在命令行上,您可能想照顾它们。然后,您所做的是我唯一想出的事情。

你不能只使用 [[NSProcessInfo processInfo] arguments]?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top