|
|
|
| Столкнулся с задачей перевода одной программы с метода FILE* на объектные потоки fstream. И возникли следующие проблемы:
1) Как делать форматный вывод в эти потоки (файлы) ? fprintf() не хочет работать с этим потоком, требует именно FILE-овый указатель. Пока решил проблему через задний проход (функция-инструмент, с переменным кол-вом аргументов, va_list'ом и vsprintf() )
2) Как записывать блоки данных в файлы в двоичном режиме ? Например, массив структур ? | |
|
|
|
|
|
|
|
для: DDK
(26.03.2007 в 14:00)
| | Посмотри в теме >Не работают fseek и fread на C++...помогите | |
|
|
|
|
|
|
|
для: rty
(26.03.2007 в 14:08)
| | Поиск такую не находит
ЗЫ: Первый вопрос отпадает, нашел. Остаётся второй. | |
|
|
|
|
|
|
|
для: DDK
(26.03.2007 в 14:00)
| | 1) У потока fstream свои дескрипторы форматирования, которые следует отправлять в поток перед выводом данных.
2) А так и записывайте, открывайте файл в режиме wb и пишите в него массив структур при помощи функции fwrite(), указывая сколько байт хотите записать (количество байт предварительно следует сосчитать). | |
|
|
|
|
|
|
|
для: cheops
(26.03.2007 в 21:16)
| | Так вот как раз fwrite-то и не катит, т.к. fstream, а не FILE | |
|
|
|
|
|
|
|
для: DDK
(27.03.2007 в 10:14)
| | Вот пример из MSDN
#include <fstream>
using namespace std;
struct Date
{
int mo, da, yr;
};
int main( )
{
Date dt = { 6, 10, 92 };
ofstream tfile( "date.dat" , ios::binary );
tfile.write( (char *) &dt, sizeof dt );
}
|
| |
|
|
|
|
|
|
|
для: oleg_alexeev
(27.03.2007 в 10:23)
| | Спасибо, все ясно ! А читать эту структуру обратно как ? | |
|
|
|
|
|
|
|
для: DDK
(27.03.2007 в 11:30)
| | Тоже из MSDN:
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
struct
{
double salary;
char name[23];
} employee;
ifstream is( "payroll" );
if( is ) { // ios::operator void*()
is.read( (char *) &employee, sizeof( employee ) );
cout << employee.name << ' ' << employee.salary << endl;
}
else {
cout << "ERROR: Cannot open file 'payroll'." << endl;
}
}
|
Заметьте, что при чтении данных блоками операторы << и >> не используются. Я лично в такой ситуации не вижу никаких причин переходить на iostream и пользуюсь старыми сишными функциями или АПИ-функциями. | |
|
|
|
|
|
|
|
для: oleg_alexeev
(27.03.2007 в 13:36)
| | Да, на самом деле я пока тоже не особо понимаю смысл перехода к этому iostream... но когда я в институте показал вот такое мной придуманное решение задачи форматного вывода в fstream:
void fstream_fprintf(fstream &outfile, char * format, ...)
{
char buffer[256];
va_list args;
va_start (args, format);
vsprintf (buffer,format, args);
outfile << buffer;
va_end (args);
}
...
fstream dbfile(DB_FILENAME_EXP, ios::out);
fstream_fprintf(dbfile, "|%-5d", MINUTE_COST);
|
...на меня посмотрели как на неочень здорового человека :))) (ну не ценят там изобретательность) | |
|
|
|
|
|
|
|
для: DDK
(27.03.2007 в 16:48)
| | Я бы Вас похвалил за то, что Вы понимаете функции с переменным числом аргументов. Но всё-таки Вы изобрели велосипед, поскольку форматированный ввод-вывод в iostream есть. Но это не такая уж большая беда поскольку Вас спровоцировали сами же преподаватели. Сначала научили вводу-выводу в стиле С а потом сказали - забудте и делайте через iostream. ИМХО, в iostream нет ничего такого, что давало бы особые преимущества в работе по сравнению с вводом-выводом в стиле С. Это пример того, как объектно-ориентированный подход не помогает в упрощении проблемы, а, скорее запутывает её. | |
|
|
|
|
|
|
|
для: oleg_alexeev
(27.03.2007 в 21:15)
| | >как объектно-ориентированный подход не помогает в упрощении проблемы, а, скорее
>запутывает её
Точнее объектно-ориентированный подход позволяет упростить лишь один класс задач (иерархических), применение его направо и налево действтительно приводит к запутыванию и увеличению объёма кода. | |
|
|
|
|
|
|
|
для: oleg_alexeev
(27.03.2007 в 21:15)
| | Тут есть еще такое соображение...
То, что в С реализовывалось через функции с переменным числом аргументов, в C++ принято достигать перегрузкой операторов с правой ассоциативностью. Тех же << .
С формальных позиций это оправданно. Хотя бы тем, что сохраняется контроль над типами аргументов, в случае vararg терявшийся начисто. Случайные попытки вывести адрес вместо самой строки и аналогичные пресекаются накорню... | |
|
|
|
|
|
|
|
для: DDK
(26.03.2007 в 14:00)
| | вопрос канечно так себе...просто забыл, напомните:
как в форматном выводе контролировать количество символов после запятой у вещественных.
ну типа в паскале это было :2:3 - вот так
а в си надо эти цифры где-то в этом месте вписывать "%f", а как и где именно не помню | |
|
|
|
|
|
|
|
для: хранитель6
(05.02.2008 в 03:44)
| | | |
|
|
|