【问题标题】:Efficient way to implement a bounded string formatting operator for use with <<?实现与 <<? 一起使用的有界字符串格式化运算符的有效方法
【发布时间】:2011-10-16 01:18:58
【问题描述】:

我正在寻找的东西在哪里:

string pearString ("pear");
string bananaString ("banana");

cout << ???? 5 ??? pearString ??????? << "[end]" << endl;
cout << ???? 5 ??? bananaString ??????? << "[end]" << endl;

将(对于某些代码字符序列???)输出:

pear[end]
banan[end]

但我希望它能够工作,而不必执行复制字符串的子字符串操作。除非我遗漏了什么,否则没有格式说明符。 (setw 说明符填充较短的字符串,但允许较长的字符串溢出。)

我想到的一个“棘手”的事情是使用自己的流输出运算符制作一个轻量级包装类。它将采用(非常量)字符串引用和其结构的限制。然后输出运算符将测试长度,如果它小于或等于限制,则执行标准输出。如果它更大,它会暂时在长度位置插入一个空字符,长度刚好足以进行输出......然后将原始字符放回去。

更新:实际上这个想法是行不通的,因为&lt;&lt; 忽略了嵌入的空值。)

无论如何,它的外观的想法是:

cout << strlimiter(5, pearString) << "[end]" << endl;
cout << strlimiter(5, bananaString) << "[end]" << endl;

有什么更简洁的解决方案可以在 const 字符串上工作并且不会从你下面弄出数据?使用其他扩展 iostream 的钩子或技巧的东西?这是否被某处的图书馆所覆盖?


更新:我忽略了 iostream 的 write 方法代替 &lt;&lt;,所以这里有一些示例代码:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

class strlimiter
{
    friend ostream& operator<< (ostream& os, strlimiter sl);

private:
    const string& data;
    size_t limit;

public:
    strlimiter(const string& data, size_t limit) : data(data), limit(limit) {}
    ~strlimiter() {}
};

ostream& operator<< (ostream& os, strlimiter sl) {
   return os.write(sl.data.c_str(), min(sl.data.length(), sl.limit));
}

int main() {
    string pearString ("pear");
    string bananaString ("banana");

    cout << strlimiter(pearString, 5) << "[end]" << endl;
    cout << strlimiter(bananaString, 5) << "[end]" << endl;

    return 0;
}

还有什么技巧可以让其在运行时的成本更少

【问题讨论】:

    标签: c++ string-formatting iostream


    【解决方案1】:

    为什么不直接使用ostreamwrite成员函数:

    cout.write(bananaString.c_str(),5);
    

    也许令人惊讶的是,您甚至可以将它放在插入链的开头。以您的示例为基础,您可以使用以下有点复杂的链:

    cout.write(bananaString.c_str(),5) << "[end]" << endl;
    

    【讨论】:

    • 使用 write 绝对是我应该想到的,由于某种原因我被困在&lt;&lt;。但是,write 方法会忽略嵌入的空值,实际上会将您所说的字节数放入流中。所以不能直接用它来解决这个问题,不用某种包装来测试长度...
    • @HostileFork: operator
    • 对,只是说我不能只使用你的第二行cout.write(bananaString.c_str(),limit) 在尝试打印到限制的一般情况下......
    【解决方案2】:

    对于您的包装类,在重载的operator&lt;&lt; 中,不要在字符串上使用&lt;&lt;,而是使用ostream::write 函数。

    the_stream.write(the_string.c_str(), the_size);
    

    【讨论】:

    • 哦。对。谢谢。添加了一些代码,请随时提出任何其他意见或改进意见...
    猜你喜欢
    • 1970-01-01
    • 2011-10-06
    • 2011-11-13
    • 2021-10-06
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    相关资源
    最近更新 更多