如何最好地输出以下代码

#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
    //

}

最佳答案

没有直接将CFString写入任何文件(包括stdout或stderr)的API,因为只能将字节写入文件字符是一个(有点)比较理想的概念;它们太高级了,无法写入文件。就像说“我想写这些像素”;你必须首先决定用什么格式(比如PNG)来写,然后用那种格式编码,然后再写数据。
角色也是如此必须以某种格式将它们编码为字节,然后写入这些字节。
将字符编码为字节/数据
首先,你必须选择一个编码。要在终端上显示,您可能需要UTF-8,它是kCFStringEncodingUTF8对于写入文件…通常需要UTF-8事实上,除非你特别需要别的东西,否则你几乎总是想要UTF-8。
接下来,必须将字符编码为字节创建C字符串是一种方法;另一种方法是创建CFData对象;还有一种方法是直接提取字节(不以空结尾)。
要创建C字符串,请使用the CFStringGetCString function
要提取字节,use the CFStringGetBytes function
你说你想坚持使用CF,所以我们将跳过C string选项(不管怎样,它的效率都比较低,因为无论什么调用write都必须调用strlen)——它更简单,但速度较慢,特别是当你在大字符串和/或频繁使用它时。相反,我们将创建CFData。
幸运的是,CFString提供了一个API来从CFString的内容创建CFData对象。不幸的是,这只适用于创建external representation您可能不想将其写入stdout;它只适合作为常规文件的全部内容写出。
所以,我们需要降低一个级别,然后我们自己此函数接受一个缓冲区(内存区域)和该缓冲区的大小(字节)。
不要对缓冲区的大小使用CFStringGetLength。它计算字符数,而不是字节数,字符数和字节数之间的关系并不总是线性的。(例如,有些字符可以用UTF-8编码成一个字节……但不是全部。不是全部。对于其他类型,所需的字节数也有所不同。)
正确的方法是调用CFStringGetBytes两次:一次没有缓冲区(NULL),然后它将简单地告诉您它将给您多少字节(而不尝试写入您没有给它的缓冲区);然后,您创建一个该大小的缓冲区,然后用缓冲区再次调用它。
您可以使用malloc创建一个缓冲区,但您需要坚持使用CF,因此我们将改为这样做:get bytes其容量是您从第一次CFStringGetBytes调用中获得的字节数,create a CFMutableData object到相同的字节数,然后increase its length该指针是指向需要写入的缓冲区的指针;它是传递给CFStringGetBytes的第二个调用的指针。
回顾目前的步骤:
在没有缓冲区的情况下调用CFStringGetBytes以了解缓冲区需要多大。
创建该容量的CFMutableData对象,并将其长度增加到该大小。
获取CFMutableData对象的可变字节指针(它是您的缓冲区),并再次调用CFStringGetBytes,这次使用缓冲区,将字符编码为数据对象中的字节。
写出来
要将字节/数据写入纯CF格式的文件,必须使用get the data's mutable byte pointer
不幸的是,没有一个CF可以与像[NSFileHandle fileHandleWithStandardOutput]这样的好的Cocoa api相媲美创建到stdout的写流的唯一方法是使用到stdout的路径(包装在URL中)创建它。
您可以很容易地从路径创建URL;标准输出设备的路径是/dev/stdout,因此要创建URL,如下所示:

CFURLRef stdoutURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/dev/stdout"), kCFURLPOSIXPathStyle, /*isDirectory*/ false);

(当然,就像你创建的所有东西一样,你需要释放它。)
有了URL,就可以CFWriteStream然后,您必须create a write stream for the file so referenced,然后您可以open the stream(您需要write the data to itget the data's byte pointer),最后its length
请注意,如果所写内容没有以换行符结尾,则可能会丢失/未显示文本NSLog在它代表您向stderr写入时为您添加新行;当您自己向stderr写入时,您必须这样做(或承担后果)。
所以:
close the stream
Create a URL that refers to the file you want to write to.
Create a stream that can write to that file.
Open the stream.(您可以根据需要多次执行此操作,或Write bytes to the stream.
当你全部完成时,do it asynchronously

10-05 20:49
查看更多