(C ++)将指针指向字符串的一部分

时间:2014-04-15 17:49:12

标签: c++ string performance pointers

我刚刚进入本机应用程序世界,我无法弄清楚如何为字符串的一部分指定指针。

例如,我有以下内容:

std::string data = "put returns between paragraphsfor linebreak add 2 spaces at end_italic_ or **bold**indent code by 4 spacesbacktick escapes `like _so_`quote by placing > at start of line to make links";

单词return的第一个字符有索引4,最后一个有索引10.我的问题是如何指向单词return,例如,不将其复制到新字符串。

感谢。

编辑:

struct Node { 
     const char * ptrToNodeStart; 
     int nodeLen;
}

我找到了这个代码段,但有人可以解释一下如何使用它。

2 个答案:

答案 0 :(得分:2)

<强> 1。 “记忆效率”

“我的文本包含10k +字符,我可能需要1000个以上的单个文本链接,它不会真正实现内存效率” - 假设您将拥有1000个长度为10 000的字符串字符,即10 mil字节= ~9.54MB +假设一些小开销,这绝对不会消耗超过10MB的内存

<强> 2。利弊

当然,你可以用struct ures的形式处理这些“链接”,只需花一些时间思考你为什么这么做。这种方法有哪些优点?如果内存效率是您这样做的唯一原因,那么您很可能会进入 过早优化 的地下城。

<强> 3。 “如何指定指向字符串部分的指针”

std::string str = "My simple string";
Node n;
n.ptrToNodeStart = &str[3];
n.nodeLen = 6;
// n is expected to refer to string "simple" here

但实际上并非那么简单。 str是具有自动存储持续时间的对象,一旦执行离开此范围,就会释放存储字符串的内存,即您有问题1: 生存期。 ..如果你的字符串消失了,你仍然保留了Node s,这些只会变成一堆无效/悬空指针

问题2:由于没有空终止字符,您无法将Node中的此指针视为字符串。如果你将需要它,你最有可能最终会遇到C风格的容易出错的代码,这些代码会做如下的恶意:

std::string tempStr(n.nodeLen + 1, '\0');
memcpy(&tempStr[0], n.ptrToNodeStart, n.nodeLen);
// yehey !!! I can finally use this annoying Node as a normal string now ....

甚至更糟:

char *buffer = new char[n.nodeLen + 1];
memcpy(buffer, n.ptrToNodeStart, n.nodeLen);
buffer[n.nodeLen] = '\0';
// using buffer here ...
delete[] buffer;

我的建议:
  • 尽可能避免使用指针
  • 坚持使用标准库中的整洁对象
  • 转到std::string个对象,std::vector<std::string> stringParts ...
  • 使用std::string::substr()

    std::string str = "My simple string";
    std::string part = str.substr(3,6);
    // part holds string "simple" now
    

答案 1 :(得分:0)

您可以定义一个对象,该对象包含指向大字符串中开头和结尾的一对迭代器。然后,给它一个类似字符串的界面。但是,当原始字符串超出范围时,迭代器将指向必杀技,并且您的问题有望崩溃,因此使用它可能很危险。

class StringView {
public:
    typedef std::string::const_iterator iterator;
    typedef std::string::const_iterator const_iterator;
    typedef std::string::size_type size_type;

    StringView(std::string const& s, 
               size_type from, 
               size_type to): data_(&s), first_(from), last_(to) {}

    bool empty() const {return s.empty();}
    size_type length() const {return last_ - first_;}

    iterator begin() const {data_.begin() + first_;}
    iterator end() const {data_.begin() + last_;}

    // add more functions for strings here

private:
    std::string const* data_;
    std::string::size_type first_, last_;
};

当你开始这样做时,你也可以看看Monoliths "Unstrung",它解释了为什么应该改进std :: string类接口以及如何改进。

建议使用string_view类进行标准化。 STLport还包含一个示例实现。