Я ищу что-то, где:
string pearString ("pear");
string bananaString ("banana");
cout << ???? 5 ??? pearString ??????? << "[end]" << endl;
cout << ???? 5 ??? bananaString ??????? << "[end]" << endl;
Будет (для некоторой последовательности символов кода ???) выводить:
pear[end]
banan[end]
Но я бы хотел, чтобыработать без необходимости выполнять операцию подстроки, которая будет копировать строку.Если я что-то упустил, для этого нет спецификатора форматирования.(Спецификатор setw добавляет более короткие строки, но допускает переполнение более длинных строк.)
"хитрая" вещь, о которой я подумал, - создать легкий класс-обертку с собственным оператором вывода потока,Он взял бы (неконстантную) строковую ссылку и предел в своей структуре.Затем оператор вывода будет проверять длину, делать стандартный вывод, если он меньше или равен пределу.Если бы он был больше, он временно вставил бы нулевой символ в позицию длины, достаточно длинную, чтобы сделать вывод ..., а затем вернул исходный символ обратно.
( UPDATE: на самом деле эта идея не сработала бы, поскольку <<
игнорирует встроенные нули.)
В любом случае идея о том, как она будет выглядеть, будет:
cout << strlimiter(5, pearString) << "[end]" << endl;
cout << strlimiter(5, bananaString) << "[end]" << endl;
Какие-нибудь более чистые решения, которые будут работать с константными строками и не будут выводить данные из-под вас?Что-то, что использует другие хуки или приемы расширения iostream?Это где-то покрыто библиотекой?
ОБНОВЛЕНИЕ : я пропустил метод iostream write
вместо <<
, поэтомуВот пример кода:
#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;
}
Есть еще хитрость, которая может сделать это даже на меньше стоимости во время выполнения?