Форум: Форум C++Разное
Новые темы: 00
PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум C++

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: fstream, форматный вывод и прочее
 
 автор: DDK   (26.03.2007 в 14:00)   письмо автору
 
 

Столкнулся с задачей перевода одной программы с метода FILE* на объектные потоки fstream. И возникли следующие проблемы:

1) Как делать форматный вывод в эти потоки (файлы) ? fprintf() не хочет работать с этим потоком, требует именно FILE-овый указатель. Пока решил проблему через задний проход (функция-инструмент, с переменным кол-вом аргументов, va_list'ом и vsprintf() )

2) Как записывать блоки данных в файлы в двоичном режиме ? Например, массив структур ?

  Ответить  
 
 автор: rty   (26.03.2007 в 14:08)   письмо автору
 
   для: DDK   (26.03.2007 в 14:00)
 

Посмотри в теме >Не работают fseek и fread на C++...помогите

  Ответить  
 
 автор: DDK   (26.03.2007 в 16:24)   письмо автору
 
   для: rty   (26.03.2007 в 14:08)
 

Поиск такую не находит

ЗЫ: Первый вопрос отпадает, нашел. Остаётся второй.

  Ответить  
 
 автор: cheops   (26.03.2007 в 21:16)   письмо автору
 
   для: DDK   (26.03.2007 в 14:00)
 

1) У потока fstream свои дескрипторы форматирования, которые следует отправлять в поток перед выводом данных.
2) А так и записывайте, открывайте файл в режиме wb и пишите в него массив структур при помощи функции fwrite(), указывая сколько байт хотите записать (количество байт предварительно следует сосчитать).

  Ответить  
 
 автор: DDK   (27.03.2007 в 10:14)   письмо автору
 
   для: cheops   (26.03.2007 в 21:16)
 

Так вот как раз fwrite-то и не катит, т.к. fstream, а не FILE

  Ответить  
 
 автор: oleg_alexeev   (27.03.2007 в 10:23)   письмо автору
 
   для: 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 );
}

  Ответить  
 
 автор: DDK   (27.03.2007 в 11:30)   письмо автору
 
   для: oleg_alexeev   (27.03.2007 в 10:23)
 

Спасибо, все ясно ! А читать эту структуру обратно как ?

  Ответить  
 
 автор: oleg_alexeev   (27.03.2007 в 13:36)   письмо автору
 
   для: 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 и пользуюсь старыми сишными функциями или АПИ-функциями.

  Ответить  
 
 автор: DDK   (27.03.2007 в 16:48)   письмо автору
 
   для: 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);


...на меня посмотрели как на неочень здорового человека :))) (ну не ценят там изобретательность)

  Ответить  
 
 автор: oleg_alexeev   (27.03.2007 в 21:15)   письмо автору
 
   для: DDK   (27.03.2007 в 16:48)
 

Я бы Вас похвалил за то, что Вы понимаете функции с переменным числом аргументов. Но всё-таки Вы изобрели велосипед, поскольку форматированный ввод-вывод в iostream есть. Но это не такая уж большая беда поскольку Вас спровоцировали сами же преподаватели. Сначала научили вводу-выводу в стиле С а потом сказали - забудте и делайте через iostream. ИМХО, в iostream нет ничего такого, что давало бы особые преимущества в работе по сравнению с вводом-выводом в стиле С. Это пример того, как объектно-ориентированный подход не помогает в упрощении проблемы, а, скорее запутывает её.

  Ответить  
 
 автор: cheops   (28.03.2007 в 13:33)   письмо автору
 
   для: oleg_alexeev   (27.03.2007 в 21:15)
 

>как объектно-ориентированный подход не помогает в упрощении проблемы, а, скорее
>запутывает её
Точнее объектно-ориентированный подход позволяет упростить лишь один класс задач (иерархических), применение его направо и налево действтительно приводит к запутыванию и увеличению объёма кода.

  Ответить  
 
 автор: Trianon   (28.03.2007 в 21:03)   письмо автору
 
   для: oleg_alexeev   (27.03.2007 в 21:15)
 

Тут есть еще такое соображение...
То, что в С реализовывалось через функции с переменным числом аргументов, в C++ принято достигать перегрузкой операторов с правой ассоциативностью. Тех же << .
С формальных позиций это оправданно. Хотя бы тем, что сохраняется контроль над типами аргументов, в случае vararg терявшийся начисто. Случайные попытки вывести адрес вместо самой строки и аналогичные пресекаются накорню...

  Ответить  
 
 автор: хранитель6   (05.02.2008 в 03:44)   письмо автору
 
   для: DDK   (26.03.2007 в 14:00)
 

вопрос канечно так себе...просто забыл, напомните:
как в форматном выводе контролировать количество символов после запятой у вещественных.
ну типа в паскале это было :2:3 - вот так
а в си надо эти цифры где-то в этом месте вписывать "%f", а как и где именно не помню

  Ответить  
 
 автор: Фитч   (05.02.2008 в 09:02)   письмо автору
 
   для: хранитель6   (05.02.2008 в 03:44)
 

printf("%2.3f", var);

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования