Re[2]: Наследование std::ostream и форматирование вывода
От: Madkinder  
Дата: 26.03.09 09:24
Оценка:
Здравствуйте, Sergey, Вы писали:

M>>Проблема №1

M>>Все строки должны быть взяты в кавычки. Хотелось бы получить такой функционал посредством создания своего модификатора, что-то в роде:

S>Я в таких случаях обычно завожу вспомогательный тип для которого переопределяю оператор вывода, который и ставит кавычки, эскейпит запрещенные символы и т.д.. и вспомогательную шаблонную функцию.

S>Функция, как не трудно догадаться, нужна только для того чтобы не нужно было писать тип, которым инстанцируется quoted_t. Если закавычивать надо только строки, то шаблоны и функция она не нужны.

Кавычить нужно только строки, и да, внутренности нужно эскейпить. Ваш подход хорош, но для моего случая имеет пару недостатков:

  1. Слишком общий, такой гибкости мне не надо, т.к. обрабатывать нужно только строки. Ну, это просто исправить.
  2. Всё-таки используется дополнительный класс-обёртка, а его очень хотелось бы избежать. Слишком велик шанс того, что пользователь класса влепит std::string вместо quoted (а то и строковый литерал). Нельзя ли обойтись без дополнительного класса?

Покритикуйте, пожалуйста, упрощённую реализацию. Никаких граблей с неявным преобразованием типов не возникнет?
#include <iostream>
#include <string>

class quoted : public std::string {
        public:
                explicit quoted(const char * oString) : std::string(oString) { }
                explicit quoted(const std::string & oString) : std::string(oString) { }
};

std::ostream & operator<<(std::ostream & oStream, const quoted & oString) {
        using std::string;

        string s(oString.c_str());

        string::size_type i = static_cast<string::size_type>(0);

        while ((i = s.find('\"', i)) != string::npos) {
                s.insert(i, 1, '\\');
                i += 2;
        }

        oStream << "\"" << s << "\"";
        return oStream;
}


M>>Проблема №2


S>Тут вопрос — какой уровень автоматизма требуется.

Если быть точным, то хочется так:
std::fstream s("qwe.txt");

s << setindent(2) // Каждая последующая новая строка должна быть отбита 2мя tab-ами.
  << "test" << 123 << std::endl
  << "yet another test" << 567 << std::endl
  << setindent(1) // Каждая последующая новая строка должна быть отбита 1м tab-ом.
  << "test once again" << 890 << std::endl;


и на выходе:

        "test" 123
        "yet another test" 567
    "test once again" 890


M>>Следующее, что подумалось -- boost::iostreams. Ранее с boost-ом сталкиваться не приходилось, и беглый осмотр iostreams не дал результатов.

S>Это вообще не про то.

Да вот мне тоже так показалось.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.