zz
Гость
|
|
« : 27-06-2006 19:51 » |
|
У меня вопрос: Всю жизнь писал на простом C (stdio, fopen, fread и т.п.), решил переходить на C++ - STL.
Имею vector <char> vect; Требуется сохранить его в файл (в любом формате, например, двоичном, чтобы можно было его потом загрузить обратно). Как это грамотно сделать? (Через ofstream или еще как-нибудь). file << vect; - не работает - пишет: 'operator<<' not implemented in type 'ofstream' for arguments of type 'vector<char,allocator<char> >'
Хотелось бы как-нибудь сделать это быстро - за одну операцию записи.
|
|
« Последнее редактирование: 06-12-2007 18:45 от Алексей1153++ »
|
Записан
|
|
|
|
Sands
Помогающий
Offline
|
|
« Ответ #1 : 27-06-2006 20:02 » |
|
По моему, тут так просто не будет. Скорей всего только поелементная запись либо по индексу либо через итератор.
|
|
|
Записан
|
|
|
|
zz
Гость
|
|
« Ответ #2 : 27-06-2006 20:22 » |
|
Тогда вопрос: А как лучше всего решать эту задачу? Надо работать с массивом, длина которого изначально неизвестна. Кроме того его требуется сохранять в файле / загружать из файла. Это что же, надо как раньше, char *vect; / malloc / realloc / fread / fwrite? Есть ли способ проще (например, в C++ есть что-нибудь для этого)?
|
|
|
Записан
|
|
|
|
Sands
Помогающий
Offline
|
|
« Ответ #3 : 27-06-2006 21:23 » |
|
Можно и как раньше, но можно и вектор использовать. А при записи можеш либо в цикле по вектору бежать vector<char> Str; .... for(int i=0;i<Str.size();i++) { file<<Str[i]; }
или можеш перед записью выделить кусок памяти по текущему размеру вектора, перегнать туда все елементы вектора, а потом через fwrite писать их в файл. P.S. По-моему ты не там пытаешся економить. Операции чтения/записи в подобного рода задачах надо делать в лоб. Хотя если кто даст метод получше буду только благодарен
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #4 : 28-06-2006 07:27 » |
|
Во-первых, malloc и free не стоит использовать - есть new и delete, которые помимо выделения памяти ещё вызывают и конструктор с деструктором.
Во-вторых, realloc тоже не надо использовать. vector имеет переменный размер в run-time, и через push_back, pop_back и другие его методы можно добавлять в него новые элементы. Соответственно, можно и удалять элементы.
В-третьих, при работе с файлами лучше использовать потоки ifstream и ofstream, работа с которыми аналогична работе с cin, cout.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
zz
Гость
|
|
« Ответ #5 : 28-06-2006 15:05 » |
|
realloc тоже не надо использовать. vector имеет переменный размер в run-time
Так я об этом и говорю, именно поэтому я и хотел использовать vector. при работе с файлами лучше использовать потоки ifstream и ofstream, работа с которыми аналогична работе с cin, cout.
В этом, собственно, и заключался первоначальный вопрос: Хотелось бы как-нибудь сделать это быстро - за одну операцию записи.
IMHO делать это в цикле по одному байту - не самое оптимальное решение по скорости
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #6 : 28-06-2006 15:50 » |
|
Я что-то не пойму... Разве fwrite(vect,vect.size(),0,f); не прокатит?... зачем обязательно использовать STL когда в каких то вариантах и старые добрые RTL функции намного лучше?
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #7 : 28-06-2006 15:54 » |
|
IMHO делать это в цикле по одному байту - не самое оптимальное решение по скорости Откуда такое мнение? Файловые операции уже лет 20, если не более, обычно буферизируются. Записать в файловый поток не означает вызывать движение головок диска и ожидание программы. Файловые потоки имеют манипуляторы flush (сброс буфера на диск), endl (конец строки и автоматический flush), а также сбрасывают буфера при своём закрытии. Операция << вывода в поток не является записью на диск, а является записью в буфер потока. Сброс буфера на диск реализуется как блочная операция. Если же речь идёт о современных HD, то они имеют встроенные кэши мегабайтных размеров. Далее, исполнение операции записи outfilestream << vec может быть реализовано через перегрузку оператора << потока. Однако такая реализация внутри всё равно содержит цикл. Считать, что, если программист в своём коде видит не цикл, а вызов фукции, такая операция быстрее явного цикла в коде - это самообман.
|
|
« Последнее редактирование: 28-06-2006 16:02 от dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #8 : 28-06-2006 16:00 » |
|
Я что-то не пойму... Разве fwrite(vect,vect.size(),0,f); не прокатит?... зачем обязательно использовать STL когда в каких то вариантах и старые добрые RTL функции намного лучше? Что-то я не пойму... Вы об ООП представление имеете? Вектор - это объект. Занимаемая им память не есть прямое хранилище чисел типа массива. Размер объекта vector и vector.size() - это разные количества, более того, несопоставимые. К тому же содержимое объекта не обязательно хранится как последовательный участок памяти, а может быть, например, списком адресов на внутренние объекты, расположенные в памяти где угодно.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
acc15
Гость
|
|
« Ответ #9 : 28-06-2006 16:06 » |
|
Считать, что, если программист в своём коде видит не цикл, а вызов фукции, такая операция быстрее явного цикла в коде - это самообман. Есть исключения... - memcpy,memset и т.д. и это не самообман... т.к. на ассемблере под конкретную платформу... Доли секунд, но всё же это уже не самообман. А если требуется сделать миллионы memcpy? это уже 1-2 секунды. Вектор - это объект. Занимаемая им память не есть прямое хранилище чисел типа массива. Размер объекта vector и vector.size() - это разные количества, более того, несопоставимые. К тому же содержимое объекта не обязательно хранится как последовательный участок памяти, а может быть, например, списком адресов на внутренние объекты. Это я знал когда Hello world писал. STL сам не пользуюсь, т.к. имею собств. классы для таких целей, которые сделаны т.к. мне удобнее... Поэтому такая вот ошибочка вышла =) Но вообще мне кажется что речь идет именно о массиве, а не о классе "vector". Если я не прав, то кроме как именно побайтовой записи в файл другого варианта нету, т.к. данные дефрагментированы в памяти.
|
|
« Последнее редактирование: 28-06-2006 16:16 от acc15 »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #10 : 28-06-2006 16:17 » |
|
Есть исключения... - memcpy,memset и т.д. и это не самообман... т.к. на ассемблере под конкретную платформу... Доли секунд, но всё же это уже не самообман. А если требуется сделать миллионы memcpy? это уже 1-2 секунды. Если на уровне железа поддерживаются блочные операции, то да. Но речь идёт о вполне прикладной задаче, причём о её реализации на таком высоком уровне, что на уровне исходного кода последовательная или блочная работа железа явно не выражается, да и не должна выражаться. Специфика платформы в описании задачи не указана, следовательно, решение должно быть универсальным.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
zz
Гость
|
|
« Ответ #11 : 28-06-2006 18:17 » |
|
Что касается исходного вопроса Пока сделал так же, как и всегда (на чистом C): Вот это - в основном цикле (в принципе, одна строчка): if(vectsize%1024==0)vect=(char *)realloc(vect,vectsize+1024); // . . . vectsize++;
При этом запись в файл: if(fwrite(vect,1,vectsize,out)!=vectsize) sprintf(statemsg,"Невозможно записать в файл с именем %s",filename);
Если писать это на STL/C++ (этот код пишу из головы, но по-моему, должно быть так): if(vectsize%1024==0)vect.resize(vectsize+1024); Запись в файл (в принципе, тоже одна строчка): vector<char> Str; .... for(int i=0;i<Str.size();i++) { file<<Str[i]; }
Просто как-то возиться с realloc надоело, но получается C++ ничего более простого предложить не может Код упростился примерно настолько же, насколко и усложнился. Вопрос:Посоветуйте, можно ли как-нибудь проще - необязательно через STL. Пока думаю насчет AnsiString, но у меня, вообще говоря, двоичные данные, может быть и '\0' и вообще не знаю, поможет ли Что касается побайтовой работы с файлами:Действительно, разница не столь велика, как я думал Вот это копирует файл 700 Mb (побайтово) за 1мин 42 сек: int main(int argc, char* argv[]) { if(argc!=3)return 1; char c; ifstream i(argv[1],ios::in |ios::binary); ofstream o(argv[2],ios::out|ios::binary); while(i.get(c))o.put(c); return 0; }
А вот это - файл 696 Mb (блоками) - за 1 мин 05 сек: int main(int argc, char* argv[]) { char buf[2048]; int size; FILE *i,*o; if((i=fopen(argv[1],"rb"))==NULL)return 1; if((o=fopen(argv[2],"wb"))==NULL)return 1; while((size=fread(buf,1,2048,i))!=0)fwrite(buf,1,size,o); return 0; }
Вообще я раньше проводил подобные эксперименты (только побайтово - через fgetc/fputc) - скорость отличалась в 5-10 раз. P.S: Но основной вопрос все-таки в том, как грамотно работать с массивом (или вектором, или еще не знаю чем) и при этом легко сохранять его на диск.
|
|
« Последнее редактирование: 06-12-2007 18:46 от Алексей1153++ »
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #12 : 28-06-2006 18:28 » |
|
Всё же определись: с массивом или классом vector? как варианты могу предложить наследование класса vector добавив ф-ции сохранения/загрузки в/из файл(а)... А вообще смотря что тебе надо... Если нужна производительность забудь про vector...
|
|
« Последнее редактирование: 28-06-2006 18:34 от acc15 »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #13 : 28-06-2006 18:32 » |
|
Может проще описать свою задачу, чтобы отвечающим было понятно, что вообще требуется сделать?
Как работать с векторами и потоками, уже объяснялось. А вот это стремление вставить блочные операции совершенно непонятно. В STL есть классы работы с массивами, обеспечивающие максимальную производительность за счёт снижения удобства работы с ними. Но всякий класс надлежит применять в соответствии с решаемой задачей. Задача же в данном случае неопределена.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
zz
Гость
|
|
« Ответ #14 : 28-06-2006 19:03 » |
|
Прошу прощения, по ходу обсуждения вопрос немного переформулировался: Задача: Хранить большое количество (изначально неизвестное) чисел (в диапазоне от -128 до 127), которые поступают в процессе работы программы. При этом необходимо иметь произвольный доступ к каждому прочитанному ранее числу. Кроме того, необходимо в некоторый момент записать все эти числа в файл. А в некоторый другой момент - прочитать из файла.
Какие я вижу пути решения: 1. Использовать указатель char * (он же массив) Недостаток: потребуестя периодически менять размер выделенной под него памяти, т.е. делать realloc.
2. Использовать vector Недостаток: неудобно сохранять его в файл (надо делать цикл).
3. Искать другие пути Пока не знаю, что: другие классы C++ или еще что-нибудь
Вопрос: Какой из вариантов на Ваш взгляд кажется лучше, что можно сделать с недостатками (в п. 1, 2), или какие Вы видите другие пути?
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #15 : 28-06-2006 20:09 » |
|
Моё решение. Работай как с обычным массивом. Для изменения длины - SetLength (GetLength - понятно для чего) Возможно аналог данного класса есть и в стандартных библиотеках, но увы... на поиск и изучение работы с ним уйдет больше времени чем сделать свой... template <class T> class c_Array { protected: T *pPtr; unsigned long nCount; void Initialize() { pPtr = 0; nCount = 0; } public: c_Array() { Initialize(); } c_Array(unsigned long nCount) { Initialize(); SetLength(nCount); } c_Array(const c_Array &arr) { Initialize(); Copy(arr); } ~c_Array() { SetLength(0); } bool SetLength(unsigned long nNewCount,bool bDoResize = true) { if (nCount == nNewCount) return true; if (nNewCount == 0) { if (pPtr) { delete [] pPtr; pPtr = 0; } } else { if (pPtr) { T* pNewPtr = new T[nNewCount]; if (!pNewPtr) return false; if (bDoResize) for (unsigned long i=0;i<nCount && i<nNewCount;i++) pNewPtr[i] = pPtr[i]; pPtr = pNewPtr;
} else {
pPtr = new T[nNewCount]; if (!pPtr) return false;
} } nCount = nNewCount; return true; } unsigned long GetLength(void) { return nCount; } bool Add(T& item) { if (!SetLength(nCount+1)) return false; pPtr[nCount-1] = item; return true; } bool Insert(unsigned long nPos,const T& item) { if (nPos > GetLength()) return false; T* pNewPtr = new T[nCount+1]; if (!pNewPtr) return false; unsigned long i; for (i=0;i<nPos;i++) pNewPtr[i] = pPtr[i]; pNewPtr[nPos] = item; for (i=nPos+1;i<nCount+1;i++) pNewPtr[i] = pPtr[i-1]; if (pPtr) delete [] pPtr; pPtr = pNewPtr; nCount++; return true; } bool Remove(const unsigned long index) { if (index >= nCount) return false; if (nCount > 1) { T* pNewPtr = new T[nCount-1]; unsigned long i; for (i=0;i<index;i++) pNewPtr[i] = pPtr[i]; for (i=index+1;i<nCount;i++) pNewPtr[i-1] = pPtr[i]; delete [] pPtr; pPtr = pNewPtr; nCount--; return true; } else return SetLength(0,false); } bool CopyFrom(const T* source,const unsigned long count) { if (!source || !count) return false; for (unsigned long i=0;i<min(nCount,count);i++) pPtr[i] = source[i]; return true; } bool CopyTo(T* dest) const { if (!dest) return false; for (unsigned long i=0;i<nCount;i++) dest[i] = pPtr[i]; return true; }
void SetAll(const T& item) { for (unsigned long i=0;i<nCount;i++) pPtr[i] = item; } bool Set(const unsigned long index,const T& item) { if (index>=nCount) return false;
pPtr[index] = item; return true; } const T& Get(unsigned long index) const { if (index>=nCount) return pPtr[0];
return pPtr[i]; } bool Copy(const c_Array& x) { if (!SetLength(x.nCount,false)) return false; if (!CopyFrom(x.pPtr,x.nCount)) return false; return true; } operator T*() { return pPtr; } c_Array& operator=(const c_Array& x) { Copy(x); return *this; } };
т.е. пример который тебя конкретно интересует: запись: c_Array <char> abc(10); // 10 - размер изначально
abc.Add('X'); abc.Add('Y'); abc.Add('Z'); fwrite(abc,sizeof(char),abc.GetLength(),file);
или по другому ЗЫ: лучше используй что было раньше =) abc.SetLength(abc.GetLength()+1); abc[abc.GetLength()-1] = 'X'; abc.SetLength(abc.GetLength()+1); abc[abc.GetLength()-1] = 'Y'; abc.SetLength(abc.GetLength()+1); abc[abc.GetLength()-1] = 'Z'; fwrite(abc,sizeof(char),abc.GetLength(),file); чтение: abc.SetLength(размер который нужен, к примеру размер файла); fread(abc,sizeof(char),abc.GetLength(),file); Или другой вариант - наследование этого же класса: template <class T> class c_FileArray : public c_Array <T> {
public: long WriteToFile(FILE *f) { return fwrite(pPtr,sizeof(T),nCount,f); } long ReadFromFile(FILE *f) { return fread(pPtr,sizeof(T),nCount,f); } };
дальнейшее использование: запись: c_FileArray <char> farray; ... farray.Add('x'); farray.Add('y'); farray.Add('z'); // Добавляем некоторое количество... farray.WriteToFile(file); // записываем в файл ...
чтение: ... c_FileArray <char> farray;
farray.SetLength(кол-во элементов которое нужно будет считать из файла); farray.ReadFromFile(file); ...
или можно сделать операторами, тогда использовать можно именно так как ты хотел изначально: template <class T> class c_FileArray : public c_Array <T> {
public: long operator>>(FILE *f) { return fwrite(pPtr,sizeof(T),nCount,f); } long operator<<(FILE *f) { return fread(pPtr,sizeof(T),nCount,f); } };
т.е. дальше можно так: abc >> file; // запись abc << file; // чтение
и без i(o)fstream ов =) Вот собственно и всё...
|
|
« Последнее редактирование: 06-12-2007 18:47 от Алексей1153++ »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #16 : 28-06-2006 21:07 » |
|
zz, Каковы требования к быстродействию? Что значит "большое количество"? Какое максимально допустимое значение? acc15, есть такое понятие, как повторное использование кода. Собственно поэтому STL предпочтительнее самописных решений. Объяснять почему - не в этой теме.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
acc15
Гость
|
|
« Ответ #17 : 28-06-2006 21:13 » |
|
интересно почему же они забыли про >> и << для файлов? =) найди ка мне такой вариант в твоём любимом STL
|
|
|
Записан
|
|
|
|
zz
Гость
|
|
« Ответ #18 : 28-06-2006 22:10 » |
|
acc15, Спасибо за код, однако думаю, что fwrite работать не будет по той же причине: Вектор - это объект. Занимаемая им память не есть прямое хранилище чисел типа массива. Размер объекта vector и vector.size() - это разные количества, более того, несопоставимые. К тому же содержимое объекта не обязательно хранится как последовательный участок памяти, а может быть, например, списком адресов на внутренние объекты, расположенные в памяти где угодно.
Т.к. pPtr - это указатель. Хотя, конечно, перегрузить операторы <<, >> для обращения к pPtr - проблем нет. dimka, Прошу прощения, если отвлекаю вопросами не по существу - особо жестких требований к быстродействию нет. Просто хочу, чтобы программа была написана хорошим силем, а создавать циклы там, где можно без них обойтись (тем более в ущерб производительности) - IMHO не есть хороший стиль программирования. Ориентировочно (с большим запасом) максимально допустимое количество - 100 000. Во всяком случае - точно в пределах разрядности int. Хотя, конечно, проще всего было бы написать: char vector[100000]; и не напрягаться, но это IMHO тоже не есть хороший стиль программирования. Вообще как-то не верится, что в C++ нет стандартных (или почти стандартных) средств для подобных задач - вроде бы, задача довольно естественная
|
|
|
Записан
|
|
|
|
acc15
Гость
|
|
« Ответ #19 : 28-06-2006 22:26 » |
|
zz, а может стоит попробовать ? =) Вдруг случайно заработает... так невзначай =) И я в примере не vector наследовал, так что он тут вообще не причем... читай внимательнее... pPtr указатель именно на массив а не вектор и данные массива идут в памяти последовательно...
Стандартных средств лично я не знаю... Но не проще ли написать своё раз и навсегда?
|
|
« Последнее редактирование: 28-06-2006 22:33 от acc15 »
|
Записан
|
|
|
|
zz
Гость
|
|
« Ответ #20 : 28-06-2006 23:08 » |
|
acc15, извинения, я был неправ Действительно, здесь: " fwrite(abc,sizeof(char),abc.GetLength(),file);" вызывается " operator T*()", который возвращает pPtr; А не работало бы это (вернее, не так работало) в случае " fwrite(&abc,sizeof(char),abc.GetLength(),file);"
|
|
|
Записан
|
|
|
|
Anchorite
Гость
|
|
« Ответ #21 : 29-06-2006 02:40 » |
|
Ну вы, блин, даете. Пример для вестора из char. // Пишем file.write(&vect[0], sizeof(char) * vect.size());
// Читаем (vectSize - число элементов читаемых из потока) vect.resize(vectSize); file.read(&vect[0], sizeof(char) * vectSize)
Но сразу же предупрежу - данный способ работает только для встроенных типов. Для каких-то самописных классов он не пойдет.
|
|
« Последнее редактирование: 29-06-2006 02:41 от Anchorite »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #22 : 29-06-2006 06:36 » |
|
Прошу прощения, если отвлекаю вопросами не по существу - особо жестких требований к быстродействию нет. Просто хочу, чтобы программа была написана хорошим силем, а создавать циклы там, где можно без них обойтись (тем более в ущерб производительности) - IMHO не есть хороший стиль программирования. Так я и думал. Хороший стиль - это не писать того, чего не требуется, и писать как можно меньше кода без ущерба для архитектуры. Что же касается производительности, то существуют понятия "микрооптимизации" и "макрооптимизации". При этом многие полагают, что первое губит второе. Т.е. код, оптимизированный по скорости исполнения, становится нечитабельным и плохо модифицируемым. 100 000 int - это на 32-хбитной платформе 400 000 байт - меньше полумегабайта. Для десктопов или серверов, память которых измеряется уже гигабайтами, пытаться экономить байты - это пустая трата времени. Для других устройств полмегабайта может быть существенным размером, и там в самом деле нужна оптимизация. "Много" у разных людей имеет разное значение. У нас, например, люди системы многоканального видеонаблюдения делают, так их хоть байтовые, хоть блочные операции записи на диск не устраивают - тормозят файловые системы, поэтому работают с "сырым" диском - увеличение производительности примерно в 2-3 раза. Объёмы данных, естественно, десятки гигабайт. Организовывать блочную запись, где размер блока подогнан под размер дискового кластера - это, конечно, увеличение быстродействия. Однако такое решение привязывает программу к конкретному диску или классу дисков. На других дисках/разделах/файловых системах эта "оптимизация" не сработает, а, может быть, даже будет источником падения производительности. Хорошее решение - это решение, универсальность или специальность которого соотнесены с задачами программы. Вообще как-то не верится, что в C++ нет стандартных (или почти стандартных) средств для подобных задач - вроде бы, задача довольно естественная. В общем случае задача сериализации объектов не так тривиальна, как может казаться. Anchorite, да, где-то уже обсуждался вопрос о том, что vector из STL хранит данные последовательно. Правда, из того обсуждения я так и не понял, является ли это требованием стандарта или особенностью компиляторов на распространённых платформах. Поэтому я на всякий случай подобных решений не предлагаю. Пример из MSDN: // ios_streamsize.cpp // compile with: /EHsc #include <iostream> #include <fstream>
int main( ) { using namespace std; char a[16] = "any such text"; ofstream x( "test.txt" ); streamsize y = 6; x.write( a, y ); }
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Anchorite
Гость
|
|
« Ответ #23 : 29-06-2006 15:31 » |
|
Anchorite, да, где-то уже обсуждался вопрос о том, что vector из STL хранит данные последовательно. Правда, из того обсуждения я так и не понял, является ли это требованием стандарта или особенностью компиляторов на распространённых платформах. Поэтому я на всякий случай подобных решений не предлагаю. Это требование стандарта ISO/IEC 14882 Second edition 2003-10-15. Все компиляторы, с которыми я на настоящий момент работаю (MinGW GCC 3.4.2 и MSVS .NET 2005) ему соответствуют.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #24 : 29-06-2006 16:21 » |
|
Anchorite, а более ранних? Далеко не все ещё используют GCC 3.4.2 или VC++ 2005.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Anchorite
Гость
|
|
« Ответ #25 : 30-06-2006 02:33 » |
|
Не могу сказать ничего определенного.
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #26 : 03-07-2006 17:50 » |
|
Добрый день! Используй BOOST::SERIALIZE и будет тебе счастье. На сайте, www.boost.org есть пример с записью в файл. vectora сериализуются автоматически.
|
|
|
Записан
|
Странно всё это....
|
|
|
Антон (LogRus)
|
|
« Ответ #27 : 04-07-2006 18:42 » |
|
Добрый день! Используй BOOST::SERIALIZE и будет тебе счастье. На сайте, www.boost.org есть пример с записью в файл. vectora сериализуются автоматически. Ладно согласен фигню сморозил проше использовать алгоритм copy получающий итераторы начала и конца вектора плюс итератор от ostream или воспользоватся тем фактом что вектор гарантированно один не прерывный блок данных и сохранить его соотвествующем образом
|
|
|
Записан
|
Странно всё это....
|
|
|
LP
Помогающий
Offline
|
|
« Ответ #28 : 04-07-2006 19:58 » |
|
проше использовать алгоритм copy получающий итераторы начала и конца вектора плюс итератор от ostream
Я тоже за этот вариант. void serialize(const std::string& filename, const std::vector<int>& vec) { std::ofstream file(filename.c_str()); std::ostream_iterator<int> beg(file, " "); std::copy(vec.begin(), vec.end(), beg); }
void deserialize(const std::string& filename, std::vector<int>& vec) { std::ifstream file(filename.c_str()); std::istream_iterator<int> beg(file), end; std::copy(beg, end, std::back_inserter(vec)); }
Anchorite, а более ранних? Далеко не все ещё используют GCC 3.4.2 или VC++ 2005.
Можно установить STL поновее. PS Кстати, Anchorite, sizeof(char) всегда 1.
|
|
|
Записан
|
Если эта надпись уменьшается, значит ваш монитор уносят
|
|
|
Anchorite
Гость
|
|
« Ответ #29 : 05-07-2006 02:27 » |
|
PS Кстати, Anchorite, sizeof(char) всегда 1. Конечно 1 Просто я привел пример в общем виде, что бы было понятнее
|
|
|
Записан
|
|
|
|
|