ofstream не записывает буфер в файл - PullRequest
1 голос
/ 19 июля 2010

Я пытаюсь записать содержимое буфера указателя на файл, созданный ofstream.

По какой-то причине файл пуст, но содержимое буфера никогда не бывает пустым ... Что я делаю не так?

void DLog::Log(const char *fmt, ...)
{
    va_list varptr;

    va_start(varptr, fmt);

    int n = ::_vscprintf(fmt, varptr);
    char *buf = new char[n + 1];
    ::vsprintf(buf, fmt, varptr);

    va_end(varptr);

    if (!m_filename.empty())
    {

        std::ofstream ofstr(m_filename.c_str(), ios::out);

        ofstr << *buf; // contents of *buf are NEVER empty, however nothing is in file??

        ofstr.close();
    }


    delete [] buf;
}

Ответы [ 5 ]

4 голосов
/ 19 июля 2010

Ваш поток открыт перед записью на нем? Может быть что угодно, от нехватки места на диске до недостаточных разрешений.

Также у вас может быть ошибка:

ofstr << *buf;

Должно быть что-то вроде:

ofstr << buf;

Поскольку buf является char*, *buf дает char, а не char*.

Здесь имеет смысл использовать std::string вместо необработанных буферов / указателей;)

3 голосов
/ 19 июля 2010

Многие проблемы можно решить, избавившись от волосатых вещей, таких как ручное управление распределением.

Никогда не используйте new T[N] в своем коде: вместо этого используйте std::vector<T> v(N);. Просто это само по себе может решить вашу проблему, потому что указатель не мешает:

void DLog::Log(const char *fmt, ...)
{
    va_list varptr;
    va_start(varptr, fmt);

    int n = ::_vscprintf(fmt, varptr);
    std::vector<char> buf(n + 1);

    ::vsprintf(&buf[0], fmt, varptr);

    va_end(varptr);

    if (!m_filename.empty())
    {
        std::ofstream ofstr(m_filename.c_str(), ios::out);
        if (!ofstr) 
        {
            // didn't open, do some error reporting here
        }

        // copy each character to the stream
        std::copy(buf.begin(), buf.end(), std::ostream_iterator<char>(ofstr));

        // no need to close, it's done automatically
    }

    // no need to remember to delete
}

Гораздо проще читать и поддерживать. Обратите внимание, что даже лучше было бы std::string buf(n + 1);, тогда вы могли бы просто сделать ofstr << buf;. К сожалению, std::string в настоящее время не требуется для непрерывного хранения своих элементов, например std::vector. Это означает, что строка с &buf[0] не гарантированно работает. Тем не менее, я сомневаюсь, что вы найдете реализацию, где она не будет работать. Тем не менее, возможно, лучше поддерживать гарантированное поведение.

Я подозреваю проблема если вы разыменовали указатель, хотя.

2 голосов
/ 19 июля 2010

Вам необходимо очистить ofstream перед закрытием.Попробуйте ofstr.flush(); до ofstr.close(); У меня была эта ошибка некоторое время назад, когда я думал, что закрытие потока автоматически сбрасывает его, но, как оказалось, это не так.

1 голос
/ 19 июля 2010

ошибка в строке

ofstr << * buf; </p>

должно быть

ofstr << buf; </p>

0 голосов
/ 19 июля 2010

Вы должны проверить, что ofstream открыт для записи после создания.

...