从最多X个字符构造std :: string,停止在null char

时间:2015-09-09 16:54:04

标签: c++ stdstring c++03

我正在从文件中的结构中读取字符串,其中每个字符串具有固定长度,并使用'\0'填充。如果存储的字符串需要整个长度,它们不会以零终止。

我目前正在构建std::string这样的人:

// char MyString[1000];
std::string stdmystring(MyString, ARRAYSIZE(MyString));

但是,这也会复制填充。我现在可以修剪弦乐,但是有一种优雅而快速的方法可以防止复制吗?

速度比空间更重要,因为它在一个循环中运行。

2 个答案:

答案 0 :(得分:2)

简单的解决方案是:

  1. 首先计算正确的长度

    • 使用strnlen作为Dieter建议
    • std::find(MyString,MyString+ARRAYSIZE(MyString),'\0') IME不会慢任何

    请注意,如果您的字符串适合缓存,则可能会占用额外的循环成本

  2. 保留最大字符串大小(你确实说空间不太重要),然后写一个附加字符的循环,直到你耗尽宽度或点击nul(如copy_until

  3. 实际上创建了一个用nuls初始化的最大字符串,strncpy,并且如果你想要大小正确,可以选择删除unused nuls

  4. 第二个选项只使用一个循环,而第三个选项使用两个(它在字符串ctor中,然后在副本中)。但是,每个角色的push_back似乎比简单的角色分配更昂贵,所以如果#3在现实中更快,我不会感到惊讶。简介并看!

答案 1 :(得分:2)

如果大小不是问题,一种可能的方法是创建一个空的JMenuItems然后使用UIManager预分配可能需要的空间然后添加每个字符,直到遇到class FillPainter implements Painter<JComponent> { private final Color color; FillPainter(Color c) { color = c; } @Override public void paint(Graphics2D g, JComponent object, int width, int height) { g.setColor(color); g.fillRect(0, 0, width, height); } }

for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
    if ("Nimbus".equals(info.getName())) {
        try {
            UIManager.setLookAndFeel(info.getClassName());
            UIManager.getLookAndFeelDefaults().put("MenuBar:Menu[Selected].backgroundPainter",
                    new FillPainter(Color.BLUE));
            UIManager.getLookAndFeelDefaults().put("MenuBar:Menu[Selected].textForeground", Color.WHITE);
            break;
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
        break;
    }
}

std::string为你提供一个内存分配,因为你知道max_size并且字符串永远不会大于此。

对+ =运算符函数的调用可能会内联,但仍需要检查字符串是否具有所需的容量,这在您的情况下是浪费的。事实上,这可能与使用strlen首先找到字符串的确切长度相同或更差,因此您必须对其进行测试。