访问字符串对象的内容(Accessing the Content of String Objects)CFString

本文介绍了CFString对象的基本属性和操作方法,包括如何像C字符串一样获取其内容、如何像Unicode字符数组一样获取内容,以及如何处理CFString中的单个Unicode字符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CFString对象两个本质的属性是一个Unicode字符数组和数组中字符的数量。一些CFString函数不仅获取这些属性,特别是字符,去有效装换到各种需要的格式。

CFStringGetBytes函数,复制一个CFString对象的内容到一个客户端提供的字节缓冲区,在“基本转换例程”描述。它之所以在另外的章节中描述,它拥有特别适合编码转换的功能。

像C字符串一样获取内容

你可能使用一些需要C字符串参数的编程接口。由于性能原因,访问CFString内容的策略和一个常用C字符串访问一样,首先获取这个字符串适当类型的指针,如果失败了,复制内容到本地缓冲区中,

             列表1        像一个C字符串一样访问CFString内容

CFStringRef str;
    CFRange rangToProcess;
    const char* bytes;
    
    str = CFStringCreateWithCString(NULL, "Hello World", kCFStringEncodingMacRoman);
    bytes = CFStringGetCStringPtr(str, kCFStringEncodingMacRoman);
    
    if (bytes == NULL) {
        char localBuffer[10];
        Boolean success;
        success = CFStringGetCString(str, localBuffer, 10, kCFStringEncodingMacRoman);
    }

这个函数允许你指定Unicode字符串应当被转换的编码。以Ptr结尾的函数要么立即返回需要的指针,在通常情况下,他们可能返回NULL。如果是后面的情况,你应该使用CFStringGetCString。

CFStringGetCString函数缓冲区或者在栈区或者在一块分配的内存中。这些函数取得字符时可能会失败,但是这种情况仅出以下两种情形中:CFString从Unicode内容转换到指定的编码失败或者缓冲区太小了。如果你需要一个字符缓冲区副本,或者不关注代码的性能,你可以简单的调用CFStringGetCString函数,而不去尝试取得指针。

像Unicode字符创一样获取内容

字符创对象提供一对类似使用16位编码缓冲区C字符串访问CFString函数。CFStringGetCharactersPrt和CFStringGetCharacters。这些函数的主要使用方法是相同的;你可以首先尝试去获取指向字符的指针,如果失败,你尝试去拷贝字符到提供的缓冲区中。这些函数是不同的,然而,他们需要一个参数,指定字符串的长度。

列表2 阐述了这些函数常用的用法

      列表2       像Unicode字符一样访问CFString内容

CFStringRef str;
    const UniChar* chars;
    
    str = CFStringCreateWithCString(NULL, "Hello World", kCFStringEncodingMacRoman);
    chars = CFStringGetCharactersPtr(str);
    if (chars == NULL) {
        CFIndex length = CFStringGetLength(str);
        UniChar *buffer = malloc(length*sizeof(UniChar));
        CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
        free(buffer);
    }
  这个例子描述了一个分配缓冲区(malloc),而不是栈区。你可以选择使用。因为你使用CFStringGetCharacters函数需要知道缓冲区的大小,分配内存较容易实现但是不高效。如果你为字符分配内存,当然,你必须释放缓冲区当你不在使用的时候。

字符处理

一些情况下你可能需要接收CFString的内容,不是整个字符块,而是一次接收一个Unicode字符。或许你可能寻找个别字符或字符序列,例如特别的控制字符去表明“recode”的开始和结束。字符串对象给你三种途径去处理Unicode字符。

第一种方法使用CFStringGetCharacters函数,在“像Unicode字符创一样获取内容”描述了复制字符到本地缓冲区中,然后循环遍历在缓冲区中的字符。但是这种技术非常耗费内存,特别是当大量的字符被调用。

第二种方法是使用CFStringGetCharacterAtIndex函数访问一个字符在同一时间,如列表3中阐述。

          列表 3      每次获取一个字符串

CFIndex length,i;
    UniChar uchar;
    CFStringRef str;
    
    str = CFStringCreateWithCString(NULL, "Hello World", kCFStringEncodingMacRoman);
    length = CFStringGetLength(str);
    for (i = 0; i<length; i++) {
        uchar = CFStringGetCharacterAtIndex(str, i);
        printf("%c",uchar);

    }

尽管这个函数不会为一块字符而要求一大块的内存,使用循环是效率很低得。由于这个原因,使用CFStringGetCharacters函数代替。

第三种技术处理字符,如列表4所示,结合了一次性的方便与效率的批量字符串的访问。当你在做顺序处理字符的时候这些内联函数CFStringInitInlineBuffer和CFStringGetCharacterFromInlineBuffer给你快速的访问字符串的内容,使用这个编程接口,和CFStringInlineBuffer结构(通常在栈区)一起调用CFStringInitInlineBuffer函数和一个CFString字符范围。然后调用CFStringGetCharacterFromInlineBuffer多次,你需要使用一个索引到此范围内相对于开始的范围。因为这些都是内联函数他们访问CFString对象定期填补in-line缓冲区。

      列表4     在一个内联缓冲区中处理字符

 CFStringRef str;
    CFStringInlineBuffer inlineBuffer;
    CFIndex length,cnt;
    
    str = CFStringCreateWithCString(NULL, "Hello World", kCFStringEncodingMacRoman);
    length = CFStringGetLength(str);
    CFStringInitInlineBuffer(str, &inlineBuffer, CFRangeMake(0, length));
    
    for (cnt = 0; cnt < length; cnt++) {
        UniChar ch = CFStringGetCharacterFromInlineBuffer(&inlineBuffer, cnt);
    }


是在这个类中查看版本么namespace OpenXLSX { constexpr const char * XLXmlDefaultVersion = "1.0"; constexpr const char * XLXmlDefaultEncoding = "UTF-8"; constexpr const bool XLXmlStandalone = true; constexpr const bool XLXmlNotStandalone = false; /** * @brief The XLXmlSavingDeclaration class encapsulates the properties of an XML saving declaration, * that can be used in calls to XLXmlData::getRawData to enforce specific settings */ class OPENXLSX_EXPORT XLXmlSavingDeclaration { public: // ===== PUBLIC MEMBER FUNCTIONS ===== // XLXmlSavingDeclaration() : m_version(XLXmlDefaultVersion), m_encoding(XLXmlDefaultEncoding), m_standalone(XLXmlNotStandalone) {} XLXmlSavingDeclaration(XLXmlSavingDeclaration const & other) = default; // copy constructor XLXmlSavingDeclaration(std::string version, std::string encoding, bool standalone = XLXmlNotStandalone) : m_version(version), m_encoding(encoding), m_standalone(standalone) {} ~XLXmlSavingDeclaration() {} /** * @brief: getter functions: version, encoding, standalone */ std::string const & version() const { return m_version; } std::string const & encoding() const { return m_encoding; } bool standalone_as_bool() const { return m_standalone; } std::string const standalone() const { return m_standalone ? "yes" : "no"; } private: // ===== PRIVATE MEMBER VARIABLES ===== // std::string m_version; std::string m_encoding; bool m_standalone; }; /** * @brief The XLXmlData class encapsulates the properties and behaviour of the .xml files in an .xlsx file zip * package. Objects of the XLXmlData type are intended to be stored centrally in an XLDocument object, from where * they can be retrieved by other objects that encapsulates the behaviour of Excel elements, such as XLWorkbook * and XLWorksheet. */ class OPENXLSX_EXPORT XLXmlData final { public: // ===== PUBLIC MEMBER FUNCTIONS ===== // /** * @brief Default constructor. All member variables are default constructed. Except for * the raw XML data, none of the member variables can be modified after construction. Hence, objects created * using the default constructor can only serve as null objects and targets for the move assignemnt operator. */ XLXmlData() = default; /** * @brief Constructor. This constructor creates objects with the given parameters. the xmlId and the xmlType * parameters have default values. These are only useful for relationship (.rels) files and the * [Content_Types].xml file located in the root directory of the zip package. * @param parentDoc A pointer to the parent XLDocument object. * @param xmlPath A std::string with the file path in zip package. * @param xmlId A std::string with the relationship ID of the file (used in the XLRelationships class) * @param xmlType The type of object the XML file represents, e.g. XLWorkbook or XLWorksheet. */ XLXmlData(XLDocument* parentDoc, const std::string& xmlPath, const std::string& xmlId = "", XLContentType xmlType = XLContentType::Unknown); /** * @brief Default destructor. The XLXmlData does not manage any dynamically allocated resources, so a default * destructor will suffice. */ ~XLXmlData(); /** * @brief check whether class is linked to a valid XML document * @return true if the class should have a link to valid data * @return false if accessing any other properties / methods could cause a segmentation fault */ bool valid() const { return m_xmlDoc != nullptr; } /** * @brief Copy constructor. The m_xmlDoc data member is a XMLDocument object, which is non-copyable. Hence, * the XLXmlData objects have a explicitly deleted copy constructor. * @param other */ XLXmlData(const XLXmlData& other) = delete; /** * @brief Move constructor. All data members are trivially movable. Hence an explicitly defaulted move * constructor is sufficient. * @param other */ XLXmlData(XLXmlData&& other) noexcept = default; /** * @brief Copy assignment operator. The m_xmlDoc data member is a XMLDocument object, which is non-copyable. * Hence, the XLXmlData objects have a explicitly deleted copy assignment operator. */ XLXmlData& operator=(const XLXmlData& other) = delete; /** * @brief Move assignment operator. All data members are trivially movable. Hence an explicitly defaulted move * constructor is sufficient. * @param other the XLXmlData object to be moved from. * @return A reference to the moved-to object. */ XLXmlData& operator=(XLXmlData&& other) noexcept = default; /** * @brief Set the raw data for the underlying XML document. Being able to set the XML data directly is useful * when creating a new file using a XML file template. E.g., when creating a new worksheet, the XML code for * a minimum viable XLWorksheet object can be added using this function. * @param data A std::string with the raw XML text. */ void setRawData(const std::string& data); /** * @brief Get the raw data for the underlying XML document. This function will retrieve the raw XML text data * from the underlying XMLDocument object. This will mainly be used when saving data to the .xlsx package * using the save function in the XLDocument class. * @param savingDeclaration @optional specify an XML saving declaration to use * @return A std::string with the raw XML text data. */ std::string getRawData(XLXmlSavingDeclaration savingDeclaration = XLXmlSavingDeclaration{}) const; /** * @brief Access the parent XLDocument object. * @return A pointer to the parent XLDocument object. */ XLDocument* getParentDoc(); /** * @brief Access the parent XLDocument object. * @return A const pointer to the parent XLDocument object. */ const XLDocument* getParentDoc() const; /** * @brief Retrieve the path of the XML data in the .xlsx zip archive. * @return A std::string with the path. */ std::string getXmlPath() const; /** * @brief Retrieve the relationship ID of the XML file. * @return A std::string with the relationship ID. */ std::string getXmlID() const; /** * @brief Retrieve the type represented by the XML data. * @return A XLContentType getValue representing the type. */ XLContentType getXmlType() const; /** * @brief Access the underlying XMLDocument object. * @return A pointer to the XMLDocument object. */ XMLDocument* getXmlDocument(); /** * @brief Access the underlying XMLDocument object. * @return A const pointer to the XMLDocument object. */ const XMLDocument* getXmlDocument() const; /** * @brief Test whether there is an XML file linked to this object * @return true if there is no underlying XML file, otherwise false */ bool empty() const; private: // ===== PRIVATE MEMBER VARIABLES ===== // XLDocument* m_parentDoc {}; /**< A pointer to the parent XLDocument object. >*/ std::string m_xmlPath {}; /**< The path of the XML data in the .xlsx zip archive. >*/ std::string m_xmlID {}; /**< The relationship ID of the XML data. >*/ XLContentType m_xmlType {}; /**< The type represented by the XML data. >*/ mutable std::unique_ptr<XMLDocument> m_xmlDoc; /**< The underlying XMLDocument object. >*/ }; } // namespace OpenXLSX
最新发布
06-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值