我正在从文件中的结构中读取字符串,其中每个字符串具有固定长度,并使用'\0'
填充。如果存储的字符串需要整个长度,它们不会以零终止。
我目前正在构建std::string
这样的人:
// char MyString[1000];
std::string stdmystring(MyString, ARRAYSIZE(MyString));
但是,这也会复制填充。我现在可以修剪弦乐,但是有一种优雅而快速的方法可以防止复制吗?
速度比空间更重要,因为它在一个循环中运行。
答案 0 :(得分:2)
简单的解决方案是:
首先计算正确的长度
strnlen
作为Dieter建议std::find(MyString,MyString+ARRAYSIZE(MyString),'\0')
IME不会慢任何请注意,如果您的字符串适合缓存,则可能会占用额外的循环成本
保留最大字符串大小(你确实说空间不太重要),然后写一个附加字符的循环,直到你耗尽宽度或点击nul(如copy_until
)
实际上创建了一个用nuls初始化的最大字符串,strncpy
,并且如果你想要大小正确,可以选择删除unused
nuls
第二个选项只使用一个循环,而第三个选项使用两个(它在字符串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首先找到字符串的确切长度相同或更差,因此您必须对其进行测试。