Как легко расположить вывод с отступом к ofstream?

Если Вы просто ищете чрезвычайно точные измерения [1 114] прошедшее время , используйте System.nanoTime(). System.currentTimeMillis() даст Вам самое точное прошедшее время в миллисекундах, так как эпоха, но System.nanoTime() дает Вам точное наносекундой время, относительно некоторой произвольной точки.

Из Документации Java:

public static long nanoTime()

Возвраты текущее значение самого точного доступного системного таймера, в наносекундах.

Этот метод может только использоваться для измерения прошедшего времени и не связан ни с каким другим понятием системы или тактовое стеной время. Возвращенное значение представляет наносекунды с некоторого фиксированного, но произвольного момента времени (возможно, в будущем, таким образом, значения могут быть отрицательными). Этот метод обеспечивает точность наносекунды, но не обязательно точность наносекунды. Никакие гарантии не сделаны о том, как часто значения изменяются. Различия в последовательных вызовах, которые охватывают больше, чем приблизительно 292 года (2 63 глоток> наносекунды) точно не вычислят прошедшее время из-за числового переполнения.

, Например, для измерения, сколько времени некоторый код берет для выполнения:

long startTime = System.nanoTime();    
// ... the code being measured ...    
long estimatedTime = System.nanoTime() - startTime;

См. также: JavaDoc System.nanoTime () и JavaDoc System.currentTimeMillis () для большего количества информации

17
задан WilliamKF 8 September 2009 в 03:09
поделиться

4 ответа

Это идеальная ситуация для использования фасета.

Пользовательская версия фасета codecvt может быть встроена в поток.

Таким образом, ваше использование будет выглядеть следующим образом:

int main()
{
    /* Imbue std::cout before it is used */
    std::ios::sync_with_stdio(false);
    std::cout.imbue(std::locale(std::locale::classic(), new IndentFacet()));

    std::cout << "Line 1\nLine 2\nLine 3\n";

    /* You must imbue a file stream before it is opened. */
    std::ofstream       data;
    data.imbue(indentLocale);
    data.open("PLOP");

    data << "Loki\nUses Locale\nTo do something silly\n";
}

Определение фасета немного сложное.
Но все дело в том, что кому-то, использующему фасет, не нужно ничего знать о форматировании. Форматирование применяется независимо от того, как используется поток.

#include <locale>
#include <algorithm>
#include <iostream>
#include <fstream>

class IndentFacet: public std::codecvt<char,char,std::mbstate_t>
{
  public:
   explicit IndentFacet(size_t ref = 0): std::codecvt<char,char,std::mbstate_t>(ref)    {}

    typedef std::codecvt_base::result               result;
    typedef std::codecvt<char,char,std::mbstate_t>  parent;
    typedef parent::intern_type                     intern_type;
    typedef parent::extern_type                     extern_type;
    typedef parent::state_type                      state_type;

    int&    state(state_type& s) const          {return *reinterpret_cast<int*>(&s);}
  protected:
    virtual result do_out(state_type& tabNeeded,
                         const intern_type* rStart, const intern_type*  rEnd, const intern_type*&   rNewStart,
                         extern_type*       wStart, extern_type*        wEnd, extern_type*&         wNewStart) const
    {
        result  res = std::codecvt_base::noconv;

        for(;(rStart < rEnd) && (wStart < wEnd);++rStart,++wStart)
        {
            // 0 indicates that the last character seen was a newline.
            // thus we will print a tab before it. Ignore it the next
            // character is also a newline
            if ((state(tabNeeded) == 0) && (*rStart != '\n'))
            {
                res                 = std::codecvt_base::ok;
                state(tabNeeded)    = 1;
                *wStart             = '\t';
                ++wStart;
                if (wStart == wEnd)
                {
                    res     = std::codecvt_base::partial;
                    break;
                }
            }
            // Copy the next character.
            *wStart         = *rStart;

            // If the character copied was a '\n' mark that state
            if (*rStart == '\n')
            {
                state(tabNeeded)    = 0;
            }
        }

        if (rStart != rEnd)
        {
            res = std::codecvt_base::partial;
        }
        rNewStart   = rStart;
        wNewStart   = wStart;

        return res;
    }

    // Override so the do_out() virtual function is called.
    virtual bool do_always_noconv() const throw()
    {
        return false;   // Sometime we add extra tabs
    }

};

См .: Примечания Тома ниже

21
ответ дан 30 November 2019 в 12:36
поделиться

Ну, это не тот ответ, который я ищу, но если такого ответа нет, вот способ сделать это вручную:

void
indentedOutput(ostream &outStream, const char *message, bool &newline)
{
  while (char cur = *message) {
    if (newline) {
      outStream << "  ";
      newline = false;
    }
    outStream << cur;
    if (cur == '\n') {
      newline = true;
    }
    ++message;
  }
}
2
ответ дан 30 November 2019 в 12:36
поделиться

Способ добавить такую ​​функцию - написать фильтрующий streambuf (т. Е. Streambuf, который перенаправляет операцию ввода-вывода другому streambuf, но манипулирует передаваемыми данными), который добавляет отступ как часть своего фильтра операция. Я привел пример написания streambuf здесь , и boost предоставляет библиотеку , чтобы помочь в этом.

Если ваш случай, член overflow () просто проверит на '\ n 'а затем при необходимости добавьте отступ сразу после него (именно то, что вы сделали в своей функции indentedOuput , за исключением того, что новая строка будет членом streambuf). Вероятно, у вас может быть настройка для увеличения или уменьшения размера отступа (возможно, доступная через манипулятор, манипулятор должен будет выполнить dynamic_cast, чтобы гарантировать, что streambuf, связанный с потоком, имеет правильный тип; есть механизм для добавления пользовательских данных в поток - basic_ios :: xalloc, iword и pword - но здесь мы хотим воздействовать на streambuf).

2
ответ дан 30 November 2019 в 12:36
поделиться

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

Например, вы можете написать функцию, которая регистрирует рекурсивную структуру. Для каждого уровня рекурсии отступ увеличивается:

std::ostream& operator<<(std::ostream& stream, Parameter* rp) 
{
    stream << "Parameter: " << std::endl;

    // Get current indent
    int w = format::get_indent(stream);

    stream << "Name: "  << rp->getName();
    // ... log other attributes as well

    if ( rp->hasParameters() )
    {
        stream << "subparameter (" << rp->getNumParameters() << "):\n";

        // Change indent for sub-levels in the hierarchy
        stream << format::indent(w+4);

        // write sub parameters        
        stream << rp->getParameters();
    }

    // Now reset indent
    stream << format::indent(w);

    return stream; 

}
1
ответ дан 30 November 2019 в 12:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: