Как записать в буфер памяти с файлом *? - PullRequest
38 голосов
/ 12 февраля 2009

Есть ли способ создать буфер памяти как ФАЙЛ *. В TiXml он может печатать xml в ФАЙЛ *, но я не могу заставить его печатать в буфер памяти.

Ответы [ 6 ]

62 голосов
/ 18 января 2012

Существует POSIX способ использовать память в качестве дескриптора FILE: fmemopen или open_memstream, в зависимости от желаемой семантики: Разница между fmemopen и open_memstream

21 голосов
/ 12 февраля 2009

Полагаю, правильный ответ - Кевин. Но вот взломать это с помощью FILE *. Обратите внимание, что если размер буфера (здесь 100000) слишком мал, вы потеряете данные, так как они записываются при сбросе буфера. Также, если программа вызывает fflush (), вы теряете данные.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    FILE *f = fopen("/dev/null", "w");
    int i;
    int written = 0;
    char *buf = malloc(100000);
    setbuffer(f, buf, 100000);
    for (i = 0; i < 1000; i++)
    {
        written += fprintf(f, "Number %d\n", i);
    }
    for (i = 0; i < written; i++) {
        printf("%c", buf[i]);
    }
}
9 голосов
/ 13 октября 2009

fmemopen может создавать ФАЙЛ из буфера, имеет ли это для вас смысл?

4 голосов
/ 13 октября 2009

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

#include <unistd.h> 
#include <stdio.h> 

int main(){
  int p[2]; pipe(p); FILE *f = fdopen( p[1], "w" );

  if( !fork() ){
    fprintf( f, "working" );
    return 0;
  }

  fclose(f); close(p[1]);
  char buff[100]; int len;
  while( (len=read(p[0], buff, 100))>0 )
    printf(" from child: '%*s'", len, buff );
  puts("");
}
2 голосов
/ 12 февраля 2009

Вы можете использовать CStr метод TiXMLPrinter , который в документации указано:

TiXmlPrinter полезен, когда вы нужно:

  1. Печать в память (особенно в режиме без STL)
  2. Управление форматированием (окончания строк и т. Д.)
1 голос

C ++ basic_streambuf наследование

В C ++ вы должны избегать FILE*, если можете.

Используя только stdlib C ++, можно создать один интерфейс, который прозрачно использует файловый или оперативный ввод-вывод.

Используются методы, упомянутые в: Установка внутреннего буфера, используемого стандартным потоком (pubsetbuf)

#include <cassert>
#include <cstring>
#include <fstream>
#include <iostream>
#include <ostream>
#include <sstream>

/* This can write either to files or memory. */
void write(std::ostream& os) {
    os << "abc";
}    

template <typename char_type>
struct ostreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> > {
    ostreambuf(char_type* buffer, std::streamsize bufferLength) {
        this->setp(buffer, buffer + bufferLength);
    }
};

int main() {
    /* To memory, in our own externally supplied buffer. */
    {
        char c[3];
        ostreambuf<char> buf(c, sizeof(c));
        std::ostream s(&buf);
        write(s);
        assert(memcmp(c, "abc", sizeof(c)) == 0);
    }

    /* To memory, but in a hidden buffer. */
    {
        std::stringstream s;
        write(s);
        assert(s.str() == "abc");
    }

    /* To file. */
    {
        std::ofstream s("a.tmp");
        write(s);
        s.close();
    }

    /* I think this is implementation defined.
     * pusetbuf calls basic_filebuf::setbuf(). */
    {
        char c[3];
        std::ofstream s;
        s.rdbuf()->pubsetbuf(c, sizeof c);
        write(s);
        s.close();
        //assert(memcmp(c, "abc", sizeof(c)) == 0);
    }
}

К сожалению, кажется невозможным обменяться FILE* и fstream: Получение ФАЙЛА * из std :: fstream

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