[英]Writing a CFSTR to the terminal in Mac OS X
我将如何最好地输出以下代码
#include <CoreFoundation/CoreFoundation.h> // Needed for CFSTR
int main(int argc, char *argv[])
{
char *c_string = "Hello I am a C String. :-).";
CFStringRef cf_string = CFStringCreateWithCString(0, c_string, kCFStringEncodingUTF8);
// output cf_string
//
}
没有API可以将CFString直接写入任何文件(包括stdout或stderr),因为您只能将字节写入文件。 字符是(某种程度上)更理想的概念。 它们太高级了,无法写入文件。 就像说“我要写这些像素”一样; 您必须首先决定以哪种格式写入它们(例如PNG),然后以该格式对其进行编码,然后写入该数据。
字符也是如此。 您必须以某种格式将它们编码为字节,然后写入这些字节。
首先,您必须选择一种编码。 为了在终端上显示,您可能需要UTF-8,即kCFStringEncodingUTF8
。 为了写入文件……您通常需要UTF-8。 实际上,除非您特别需要其他东西,否则几乎总是需要UTF-8。
接下来,您必须将字符编码为字节。 创建C字符串是一种方法。 另一个是创建一个CFData对象; 还有一个方法是直接提取字节(不以null结尾)。
CFStringGetCString
函数 。 CFStringGetBytes
函数 。 您说过要坚持使用CF,所以我们将跳过C字符串选项(无论如何,它效率不高,因为无论调用write
还是必须调用strlen
),它更容易但更慢,尤其是在将其用于大串和/或频繁。 相反,我们将创建CFData。
幸运的是,CFString提供了一个API,可以根据CFString的内容创建CFData对象。 不幸的是,这仅适用于创建外部表示 。 您可能不想将其写入stdout。 仅适合作为常规文件的全部内容写出。
因此,我们需要降低一个级别并自己获取字节 。 该函数需要一个缓冲区(内存区域)以及该缓冲区的大小(以字节为单位)。
不要将CFStringGetLength
用作缓冲区的大小。 这是对字符而不是字节进行计数,并且字符数与字节数之间的关系并不总是线性的。 (例如,某些字符可以用UTF-8编码为单个字节…,但不是全部。不是几乎全部。对于其他字符,所需的字节数有所不同。)
正确的方法是两次调用CFStringGetBytes
:一次没有缓冲区( NULL
),然后它将简单地告诉您它将给您多少字节(而无需尝试写入未分配给它的缓冲区); 然后,创建该大小的缓冲区,然后使用该缓冲区再次调用它。
您可以使用malloc
创建一个缓冲区,但是您想坚持使用CF东西,所以我们将采用这种方式: 创建一个CFMutableData对象,其容量为您从第一个CFStringGetBytes
调用中获取的字节数, 将其长度增加为相同数量的字节,然后获取数据的可变字节指针 。 该指针是您需要写入缓冲区的指针。 它是您传递给第二次调用CFStringGetBytes
的指针。
回顾到目前为止的步骤:
CFStringGetBytes
带缓冲区的CFStringGetBytes
以找出缓冲区需要多大。 CFStringGetBytes
,以将字符编码为数据对象中的字节。 要将字节/数据写入纯CF中的文件,必须使用CFWriteStream 。
可悲的是,没有像[NSFileHandle fileHandleWithStandardOutput]
这样的漂亮的Cocoa API可以使用[NSFileHandle fileHandleWithStandardOutput]
创建到stdout的写流的唯一方法是使用包装在URL中的stdout路径来创建它。
您可以很容易地从路径创建URL。 标准输出设备的路径是/dev/stdout
,因此创建URL的过程如下所示:
CFURLRef stdoutURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/dev/stdout"), kCFURLPOSIXPathStyle, /*isDirectory*/ false);
(当然,就像您创建的所有内容一样,您需要释放它。)
有了URL,您就可以为这样引用的文件创建写流 。 然后,您必须打开流 ,然后可以向其中写入数据 (您将需要获取数据的字节指针 及其长度 ),最后关闭流 。
请注意,如果您写的内容不是以换行符结尾,则可能缺少/未显示文本。 NSLog
代表您写入stderr时,会为您添加换行符。 当您自己写信给stderr时,您必须这样做(否则后果自负)。
所以:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.