【问题标题】:Proper way to convert char* to NSString without initWithCString?在没有 initWithCString 的情况下将 char* 转换为 NSString 的正确方法?
【发布时间】:2011-12-14 14:59:47
【问题描述】:

我正在将 SQLite3 数据库中的结果列表提取到 UITableView 中。我从数据库中提取文本的代码是这样的:

char *menuNameChars = (char *) sqlite3_column_text(statement, 1);
NSString *menuName = [[NSString alloc] initWithUTF8String:menuNameChars];
NSLog(@"Retrieved %s,%@ from DB.", menuNameChars, menuName);

当我使用initWithUTF8String 时,有时会从数据库中正确复制信息。但有时,来自char* 的信息会正确显示,但来自NSString 的信息不会:

2011-10-24 22:26:54.325 [23974:207] Retrieved Cravin Chicken Sandwich – Crispy, (null) from DB.
2011-10-24 22:26:54.327 [23974:207] Retrieved Cravin Chicken Sandwich – Roast, (null) from DB.
2011-10-24 22:26:54.331 [23974:207] Retrieved Jr Chicken Sandwich, Jr Chicken Sandwich from DB.
2011-10-24 22:26:54.337 [23974:207] Retrieved Prime-Cut Chicken Tenders - 3 Piece, Prime-Cut Chicken Tenders - 3 Piece from DB.

现在,如果我将 initWithUTF8String 替换为 initWithCString,则代码可以完美运行。但是,XCode 4.2 告诉我 initWithCString 已被弃用。我知道的足够了解我不想使用已弃用的代码,但如果 initWithUTF8String 不起作用,我应该使用什么?

【问题讨论】:

  • 你试过[NSString stringWithFormat:@"%s", menuNameChars]吗?
  • 为什么不使用像 FMDB github.com/ccgus/fmdb 这样的 sqlite 包装器?
  • @Dani 那么为什么不使用 Core Data 呢?更容易。
  • @WTP: 可能他已经有一个mysql数据库了?
  • @DanielRHicks:我还没有尝试过,但是如果 stringWithFormat 与 NSLog 一样,那肯定是一个解决方案! @Dani/@WTP:我实际上打算在这个程序中使用 FMDB 包装器,但是当我尝试添加 FMDB 代码时,它导致了一些 EXC_BAD_ACCESS 错误,所以我暂时将 FMDB 放在了次要位置。至于 Core Data,我还没有学会如何使用 Core Data(还)。不过它在待办事项列表上!

标签: objective-c ios nsstring char


【解决方案1】:

我可以看到您的第一行日志中的破折号 (Retrieved Cravin Chicken Sandwich ...) 不是简单的 ASCII HYPHEN-MINUS (U+002D, UTF-8 2D)。这是一个 Unicode EN DASH 字符(U+2013,UTF-8 E2 80 93)。第二行也一样。我的猜测是它们在您的数据库中的编码不正确。如果你给 -[NSString initWithUTF8String:] 一个不是有效 UTF-8 的 C 字符串,它会返回 nil

尝试打印menuNameChars 的十六进制转储。您可以通过在调用sqlite3_column_text 之后的行上设置断点来做到这一点。到达断点时,右键单击/控制单击堆栈框架窗口中的menuNameChars,然后选择View memory of "*menuNameChars"(注意*)。

【讨论】:

  • 由于打印的是“(null)”,这似乎是 Stack Overflow 上的错误,而不是实际问题。
  • 这是我的一个错误——我重新输入了代码而不是 C&P。在代码中是 %s,%@。
  • 上面@DanielRHicks 的建议解决了我的问题——但你的回答给了我原因。我正在使用 Excel 对数据库中的信息进行排序/编辑,当我使用两个连字符时,它会自动将其更正为您所说的“EN DASH”字符。这就是我的代码不起作用的原因。
【解决方案2】:

看起来数据未编码为 UTF-8。您应该找出正在使用的编码,然后使用initWithCString:encoding: 并传递正确的编码。

【讨论】:

  • 如果我使用 initWithCString 它会正确地传递给 NSString - 但是 initWithCString 已被弃用。从我在 Apple 文档中可以看出, initWithUTF8String 是替换它的函数,但它给了我上述(空)响应。有没有办法从代码中找到编码?
【解决方案3】:

试试stringWithFormat:的力量

【讨论】:

  • +1 [NSString stringWithFormat:@"%s",property_getName(property)]
【解决方案4】:

如果您仔细查看 Apple Developer,似乎实例方法 initWithCString: 仅在没有显式 encoding: 说明符的版本中被弃用。有充分的理由可以争论,因此对于将 const char * C-string 转换为 NSString 是完全有效的。请比较:

https://developer.apple.com/documentation/foundation/nsstring/1497394-initwithcstring

到较新的 initWithCString:encoding:

https://developer.apple.com/documentation/foundation/nsstring/1411950-initwithcstring?language=objc

此 Foundation API 更改自 macOS 10.4+ 起进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 2019-08-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    相关资源
    最近更新 更多