Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Ада и другие языки _ структуры и функции

Автор: Tribunal 23.10.2006 13:10

по идее программа должна иметь две ф-ии: чтение из файла данных для структуры и запись в файл структуры в конец файла.и выполнять следующе:запись в файл информации только о тех ноутбуках ,тактовая частота которых больше 120 МГц,+их нужно отсортировать в порядке возрастания цены.

то,что у меня получилось к сожалению не работает...
может посмотрите и исправите какие-то ошибки?
заранее благодарна..

#include <iostream.h>
#include <fstream.h>

typedef struct tagT
{
int disp_res_x; //разрешающая способность дисплея по горизонтали
int disp_res_y; //по вертикали

int f; //тактовая частота
float d; //размер диагонали дисплея
float hdd; //объем жесткого диска
char mode [20]; //наименование
float price; //цена
}T;

void f_read(T notebook[20])
{
ifstream fin ("file.txt");
if (!fin)
{
cout << "File file.txt don't found." << endl;
return 1;
};
int n;
fin >> n;
for (int i=0;i<n;i++)
{
fin >> notebook[i].mode >> notebook[i].hdd >> notebook[i].f >> notebook[i].d >>
notebook[i].disp_res_x >> notebook[i].disp_res_y >> notebook[i].price;
};
return;
};

void f_write(T notebook[20],int i)
{
ifstream fout ("file.txt");
if (!fout)
{
cout << "File can't open for writing." << endl;
return 1;
};
int n;
fin >> n;
fout << notebook[i].mode << notebook[i].hdd << notebook[i].f << notebook[i].d <<
notebook[i].disp_res_x << notebook[i].disp_res_y << notebook[i].price << endl;
return;
};
int main()
{
T notebook[20];

f_read(notebook[20]);
int n;
fin >> n;

T buf;
for (int i=0;i<n;i++)
for (int j=n-1;j>=i+1;j--)
{
if (notebook[j-1].price > notebook[j].price)
{
memmove (&buf, &notebook[j-1], sizeof(T));
memmove (&notebook[j-1],&notebook[j], sizeof(T));
memmove (&notebook[j], &buf, sizeof(T));
};
};

for (int i=0;i<n;i++)
{
if (notebook[i].f>120) f_write(notebook[20],i);
};
}


Автор: volvo 23.10.2006 17:52

Цитата
может посмотрите и исправите какие-то ошибки?
Тебе здесь (это С++ программа) лучше всего сделать сортировку не через memmove, а через "operator =", что будет проще и красивей... Тоже самое касается и ввода/вывода: делаешь переопределение "operator <<" и "operator >>" и все прекрасно работает...

Если тебя такое решение устроит, скажи, я помогу (чтоб просто так не делать, вдруг тебе нужно именно так, как ты начала unsure.gif )

А ошибки начинаются с того, что ты из void-функции пытаешься вернуть значение, как это? blink.gif

Автор: Tribunal 23.10.2006 17:59

честно говоря не знаю что за "operator=".но немного объяснений и я пойму=)
...а с void так вышло,потому что я пыталась ф-ию заставить работать...почему-то не получалось...в общем в итоге я запталась...а теперь вообще не знаю,как ее определить...

Автор: volvo 23.10.2006 19:39

Цитата
честно говоря не знаю что за "operator="
Смотри... Ты переопределяешь для класса оператор присваивания, то есть, задаешь действия, которые программа должна выполнить, если ты делаешь, например:

T a, b;
a = b; // <--- Вот так...


Как это сделать... Все очень просто:
#include <stdlib.h>
#include <string.h>

#include <iostream.h>
#include <fstream.h>


// Работаем с классами
class T {
// Функции "друзья" класса (имеют доступ к защищенным и приватным членам класса)

// Перегрузка операции ввода
friend ostream& operator << (ostream &, const T &);
// Перегрузка операции вывода
friend istream& operator >> (istream &in, T &note);

public:
// Вот это и есть перегрузка операции присваивания
T& operator = (const T &note) {
disp_res_x = note.disp_res_x; disp_res_y = note.disp_res_y;
f = note.f; d = note.d; hdd = note.hdd; price = note.price;
strcpy(mode, note.mode);
return *this;
}

// Конструктор по умолчанию
T(char* _model = "", float _price = 0.0, int _f = 0,
float _d = 0.0, float _hdd = 0.0, int dx = 0, int dy = 0):
price(_price), f(_f), d(_d), hdd(_hdd), disp_res_x(dx), disp_res_y(dy)
{
strcpy(mode, _model);
}

int disp_res_x;
int disp_res_y;

int f;
float d;
float hdd;
char mode[20];
float price;
};

istream& operator >> (istream &in, T &note) {
const int bufSize = 15;
char buffer[bufSize + 1];

float T;
char ch;

// 1. Reading model
for(int i = 0; i < bufSize; ++i) {
in.get(ch);
if(ch == '\t') break;
buffer[i] = ch;
}

buffer[i] = '\0';
strcpy(note.mode, buffer);

in >> note.price; // read price
in >> T; // skip mass

// Skip gabarites
for(i = 0; i < 15; ++i)
in.get(buffer[i]); buffer[15] = '\0';

in >> note.f; // read CPU freq
in >> T; // Skip memory size
in >> note.d; // reading disp diag
in >> T; // Skip videomemory

// Reading resolution
in.get(ch);
for(i = 0; i < 4; ++i)
in.get(buffer[i]); buffer[4] = '\0';
note.disp_res_x = atoi(buffer);

in.get(ch);
for(i = 0; i < 4; ++i)
in.get(buffer[i]); buffer[4] = '\0';
note.disp_res_y = atoi(buffer);


in >> T; // Skip monitor freq, read HDD
in >> note.hdd; // read HDD

// Get the "\n" symbol
in.get(ch);
return in;
}

ostream& operator << (ostream &out, const T &note) {
out << note.disp_res_x << ' ' << note.disp_res_y << ' '
<< note.f << ' ' << note.d << ' '
<< note.hdd << ' '
<< note.mode << endl;
return out;
};

int main()
{
const int n = 5;
T notebook[n];

cout << "starting..." << endl;

ifstream f_in("NOTE.TXT");
if(!f_in) {
cerr << "error opening file" << endl;
exit(-1);
}

for(int i = 0; i < n; ++i)
f_in >> notebook[i];

for(i = 0;i < n; i++)
for(int j = n-1; j >= i+1; j--) {

if (notebook[j-1].price > notebook[j].price) {
T buf = notebook[j - 1];
notebook[j - 1] = notebook[j];
notebook[j] = buf;
}

}

for(i = 0; i < 5; i++)
if(notebook[i].f > 120)
cout << notebook[i];

return 0;
}


Если что непонятно в логике работы - спрашивай... Вместо вывода на консоль через cout можно открыть ofstream f_out("res.txt") и точно так же направить вывод туда:
f_out << notebook[i];


Чтение происходило вот из этого файла:
Прикрепленный файл  NOTE.TXT ( 366 байт ) Кол-во скачиваний: 410


(он содержит для каждого ноута следующие данные:

модель, цена, масса, габариты(длина/ширина/высота), тактовая частота CPU, размер памяти, диагональ дисплея, размер видеопамяти, разрешение монитора(X/Y), рабочая частота монитора, размер хард-диска.

если у тебя формат файла данных другой, то придется подправить operator >>)

Автор: Tribunal 23.10.2006 19:46

в принципе...я могу с этим разобраться...видимо это действительно гораздо проще...
но дело в том,что по заданию классы использовать нельзя...

может всё-же попробовать исправить то,что у меня получилось?
или там совсем всё плохо?

Автор: volvo 23.10.2006 19:54

Ну, нельзя классы, так поменяй class на struct - будешь работать со структурами... В C++ это равнозначно...

blum.gif

Автор: Tribunal 23.10.2006 19:59

ок...
нет,ну всё равно ... что не так с моей программой если конкретно?

Автор: volvo 23.10.2006 20:11

Если конкретно - то я тебе уже сказал:

1. Ты не имеешь права в void-функции возвращать параметры.
2. Для вывода информации должен использоваться ofstream, а не ifstream, как у тебя...
3. В функции f_write ты почему-то ЧИТАЕШЬ из файла, который хочешь открыть на запись...

Пока исправляй это, потом посмотрим...

Автор: Tribunal 23.10.2006 20:50

теперь программа даже запускается)
так вот...а файл почему-то становится пустым.почему так происходит?

#include <iostream.h>
#include <fstream.h>

typedef struct tagT
{
int disp_res_x; //разрешающая способность дисплея по горизонтали
int disp_res_y; //по вертикали

int f; //тактовая частота
float d; //размер диагонали дисплея
float hdd; //объем жесткого диска
char mode [20]; //наименование
float price; //цена
}T;

void f_read()
{
ifstream fin ("file.txt");
if (!fin) cout << "File file.txt don't found." << endl;

T notebook[20];
int n;
fin >> n;
for (int i=0;i<n;i++)
{
fin >> notebook[i].mode >> notebook[i].hdd >> notebook[i].f >> notebook[i].d >>
notebook[i].disp_res_x >> notebook[i].disp_res_y >> notebook[i].price;
};
};

void f_write()
{
ofstream fout ("file.txt");
if (!fout) cout << "File can't open for writing." << endl;
ifstream fin ("file.txt");
if (!fin) cout << "File file.txt don't found." << endl;

T notebook[20];
int n;
int i;
fin >> n;
fout << notebook[i].mode << notebook[i].hdd << notebook[i].f << notebook[i].d <<
notebook[i].disp_res_x << notebook[i].disp_res_y << notebook[i].price << endl;
};

int main()
{
ofstream fout ("file.txt");
if (!fout) cout << "File can't open for writing." << endl;
ifstream fin ("file.txt");
if (!fin) cout << "File file.txt don't found." << endl;

T notebook[20];

f_read;

int n;
fin >> n;

T buf;
for (int i=0;i<n;i++)
for (int j=n-1;j>=i+1;j--)
{
if (notebook[j-1].price > notebook[j].price)
{
memmove (&buf, &notebook[j-1], sizeof(T));
memmove (&notebook[j-1],&notebook[j], sizeof(T));
memmove (&notebook[j], &buf, sizeof(T));
};
};

for (int i=0;i<n;i++)
{
if (notebook[i].f>120) f_write;
};
}


Автор: volvo 24.10.2006 0:37

Цитата
а файл почему-то становится пустым.почему так происходит?
Ну, запускается -то оно запускается, только вот ЧТО оно делает?

По пунктам:
1) ты описала свою копию массива notebook И в f_read И в f_write И в main... И работаешь в каждой функции со своей копией массива. А они что, как-то взаимосвязаны? Увы, они существуют только до тех пор, пока выполняется процедура... Тебе нужен здесь глобальный массив...
2) то же самое касается и переменной n
3) аналогично - с файлом. Ты открываешь в каждой функции свою копию? Напрасно, открывай для ввода одну, в f_read, больше она тебе нигде не нужна, а для вывода - открывай в main и передавай как параметр...
4) То, что ты вызываешь f_read/f_write без (), на компилятор как-то не производит впечатления, синтаксис требует со скобками smile.gif
5) я бы все-таки для вывода создавал файл с другим именем...

Вот, смотри этот вариант:

#include <iostream.h>
#include <fstream.h>

typedef struct tagT
{
int disp_res_x;
int disp_res_y;

int f;
float d;
float hdd;
char mode [20];
float price;
} T;

int n;
T notebook[20];

void f_read()
{
ifstream fin ("N.txt");
if (!fin) cout << "File file.txt don't found." << endl;

fin >> n;
for (int i=0;i<n;i++)
{
fin >> notebook[i].mode >> notebook[i].hdd >> notebook[i].f >> notebook[i].d >>
notebook[i].disp_res_x >> notebook[i].disp_res_y >> notebook[i].price;
};
};

void f_write(ostream &fout, int i)
{
fout << notebook[i].mode << " "<< notebook[i].hdd << " "<< notebook[i].f << " "
<< notebook[i].d << " "<< notebook[i].disp_res_x << " "<< notebook[i].disp_res_y << " "
<< notebook[i].price << endl;
};

int main()
{
ofstream fout ("NOut.txt");
if (!fout) cout << "File can't open for writing." << endl;

f_read();

T buf;
for (int i=0;i<n;i++)
for (int j=n-1;j>=i+1;j--)
{
if (notebook[j-1].price > notebook[j].price)
{
memmove (&buf, &notebook[j-1], sizeof(T));
memmove (&notebook[j-1],&notebook[j], sizeof(T));
memmove (&notebook[j], &buf, sizeof(T));
};
};

for (i=0;i<n;i++)
{
if (notebook[i].f>120) f_write(fout, i);
};
return 0;
}

Автор: Tribunal 30.10.2006 14:06

в общем я решила всё же сделать вот так...

а как быть ,если нужно работать с бинарными файлами?

#include <iostream.h>
#include <fstream.h>

typedef struct tagT
{
int disp_res_x; //разрешающая способность дисплея по горизонтали
int disp_res_y; //по вертикали

int f; //тактовая частота
float d; //размер диагонали дисплея
float hdd; //объем жесткого диска
char mode [20]; //наименование
float price; //цена
}T;

int n;
T notebook[20];

void f_read()
{
ifstream fin ("Note.txt");
if (!fin) cout << "File file.txt don't found." << endl;

fin >> n;
for (int i=0;i<n;i++)
{
fin >> notebook[i].mode >> notebook[i].hdd >> notebook[i].f >> notebook[i].d >>
notebook[i].disp_res_x >> notebook[i].disp_res_y >> notebook[i].price;
};
};

void f_write(ofstream &fout, int i)
{
fout << notebook[i].mode <<" " << notebook[i].hdd << " "<< notebook[i].f <<" "
<< notebook[i].d << " "<< notebook[i].disp_res_x <<" "<< notebook[i].disp_res_y <<" "
<< notebook[i].price << endl;
};

int main()
{
ofstream fout ("NoteOut.txt");
if (!fout) cout << "File can't open for writing." << endl;

f_read();

T buf;
for (int i=0;i<n;i++)
for (int j=n-1;j>=i+1;j--)
{
if (notebook[j-1].price > notebook[j].price)
{
memmove (&buf, &notebook[j-1], sizeof(T));
memmove (&notebook[j-1],&notebook[j], sizeof(T));
memmove (&notebook[j], &buf, sizeof(T));
};
};

for (int i=0;i<n;i++)
{
if (notebook[i].f>120) f_write(fout,i);
};
return 0;
}


Автор: volvo 30.10.2006 20:05

Цитата
а как быть ,если нужно работать с бинарными файлами?
"Меня терзают смутные сомнения..." (С) Я делал точно такую же задачу про ноутбуки в прошлом году... Вот это выдрано оттуда (запись в бинарный файл/чтение из него):

istream& read(istream &in, TNotebook &note)
{
return in.read((char*)&note, sizeof(note));
}
iostream& write(iostream &io, const TNotebook &note)
{
union
{
unsigned value;
char buf[2];
} size = {0};

io.seekg(0, ios::beg);
io.read(size.buf, sizeof(size.buf));
io.clear();

++size.value;
io.seekp(0, ios::beg);
io.write(size.buf, sizeof(size.buf));

io.seekp(0, ios::end);
io.write((const char*)&note, sizeof(note));
return io;
}

...
// В функции main():

fstream bin("note.bin", ios::in|ios::out|ios::binary);
for(int i = 0; i < 10; i++) {
// как-то получаешь содержимое очередного эл-та массива, например, вводишь с клавиатуры: note[ i ]
write(bin, note[ i ]); // и пишешь его в бинарный файл ...
}

bin.seekg(2, ios::beg);
// читаешь из бинарного файла очередное значение note[ i ]
while(read(bin, note[ i ])) {
// Выводишь на экран note[ i ]
}
...

Автор: Tribunal 4.11.2006 14:44

воспользовалась вашими функциями.вроде довольно успешно.
но программа записывает в файл то,что вводится с клавиатуры,а потом ничего больше не происходит.
почему такое происходит? unsure.gif

#include <iostream.h>
#include <fstream.h>

typedef struct tagT
{
int disp_res_x;
int disp_res_y;

int f;
float d;
float hdd;
char mode [20];
float price;
}T;

T notebook[20];

istream& read(istream &in, T &notebook)
{
return in.read((char*)&notebook, sizeof(notebook));
}

iostream& write(iostream &io, const T &notebook)
{
union
{
unsigned value;
char buf[2];
} size = {0};
io.seekg(0, ios::beg);
io.read(size.buf, sizeof(size.buf));
io.write((const char*)&notebook, sizeof(notebook));
return io;
}

iostream& write(iostream &io, int)
{
union
{
unsigned value;
char buf[2];
} size = {0};
io.seekg(0, ios::beg);
io.read(size.buf, sizeof(size.buf));
io.write((const char*)&notebook, sizeof(notebook));
return io;
}

int n;


int main()
{
fstream bin("note.bin", ios::in|ios::out|ios::binary);


cout << "Number of notes:";cin >> n;
write(bin,n);
for(int i = 0; i < n; i++)
{
cout << "Note#" << i+1;
cout << "name:";cin >> notebook[i].mode;
cout << "chastota:";cin >> notebook[i].f;
cout << "diagonal:";cin >> notebook[i].d;
cout << "hdd:";cin >> notebook[i].hdd;
cout << "displey resolution:";cin >> notebook[i].disp_res_x;
cout << "x";cin >> notebook[i].disp_res_y;
cout << "price:";cin >> notebook[i].price;
write(bin,notebook[i]);
}



T buf;
for (int i=0;i<n;i++)
for (int j=n-1;j>=i+1;j--)
{
if (notebook[j-1].price > notebook[j].price)
{
memmove (&buf, &notebook[j-1], sizeof(T));
memmove (&notebook[j-1],&notebook[j], sizeof(T));
memmove (&notebook[j], &buf, sizeof(T));
};
};

bin.seekg(2, ios::beg);
for (int i=0;i<n;i++)
{
if (notebook[i].f>120) write(bin,notebook[i]);
}

for (int i=0;i<n;i++)
{
while (read(bin,notebook[i]))
{
cout << "Note#" << i;
cout << "name:" << notebook[i].mode << endl;
cout << "chastota:" << notebook[i].f << endl;
cout << "diagonal:" << notebook[i].d << endl;
cout << "hdd:" << notebook[i].hdd << endl;
cout << "displey resolution:" << notebook[i].disp_res_x;
cout << "x" << notebook[i].disp_res_y << endl;
cout << "price:" << notebook[i].price << endl;
};
}

}

Автор: Tribunal 7.11.2006 21:34

помогите.. unsure.gif
не могу найти ошибку...=(

Автор: Tribunal 10.11.2006 22:02

я вот попробовала написать ф-ии вот так,но заступорилась на функции для считывания.
да и то,что написано выше...там я пытаюсь первые 2 байта файла читать как размерность массива структуры.
+мне же нужно ДОписывать в файл полученные данные после выполнения программы...
я совсем запуталась(( очень прошу о помощи.

int append_data(const Notebook &note,const char* filename)
{
FILE *fout;
if ((fout=fopen(filename,"ab")) == null) return 1;
int success=fwrite(&note,sizeof(note),1,fout);
fclose(fout);
if (success==1) return 0;
else return 2;
}

int print_data(const char * filename)
{
int num;
Notebook note;
FILE *f;
if ((f=fopen(filename,"rb"))==null) return 1;
fseek(f,0,seek_end);
int n_record=ftell(f)/sizeof(note);
while (true)
{
for (int i=0;i<n;i++)
{
fseek(f,i*sizeof(note),seek_set);
fread(&notebook.sizeof(note),1,f);
printf("%30s%5i%10,2f\n",
note.disp_res_x,note.disp_res_y,note.f,note.d,note.hdd,note.mode,note.price);
}
}
return 0;
}

Автор: Алена 12.11.2006 2:06

Цитата
программа записывает в файл то,что вводится с клавиатуры,а потом ничего больше не происходит. почему такое происходит?
Потому, что перед чтением из файла:

    while (read(bin,notebook[i])) ...

нужно опять перебросить stream position на начало, как ты уже делала раньше:
bin.seekg(2, ios::beg);

Если этого не сделать, то из потока ничего читаться не будет, т.к. после записи в него указатель находится в самом конце потока...

Это первое...

Второе - расскажи мне, зачем тебе внешний цикл for? У тебя же есть цикл while, который будет читать данные до тех пор, пока файл не закончится, а в твоем случае чтение будет происходить на итерации i=0 и ВСЕ данные будут записаны в нулевую ячейку массива, остальные заполнены не будут (я о программе из поста №13)...

Автор: Tribunal 12.11.2006 14:35

спасибо,конечно,
но мне это к сожалению не помогло...
всё равно получается так,что идет запрос на заполнение файла,я ввожу данные,после чего больше ничего не происходит.=(

Автор: Алена 12.11.2006 14:50

Присоедини сюда окончательный вариант программы, с которым работаешь (лучше - в аттач), и полностью напиши те данные, которые вводишь, в какой последовательности ты это делаешь, и ЧТО ИМЕННО ты хочешь, чтобы при этом происходило...

Автор: Tribunal 12.11.2006 15:00

я ввожу кол-во записей,затем по порядку все поля записи.
затем всё это по идее должно писаться в бинарный файл.
далее я сортирую массив записей по возрастанию цен,так как затем мне нужно результат вывести именно таким образом.
затем я ввожу условие частота>120.если оно выполняется,запись пишется в конец бинарного файла.
после всего этого хотелось бы,чтобы результат был выведен на экран.

хммм...а ведь у меня в программе получается должен выводиться весь файл.
ух...кажется,я совсем запуталась=(


Прикрепленные файлы
Прикрепленный файл  main.rar ( 794 байт ) Кол-во скачиваний: 151

Автор: Алена 12.11.2006 16:06

Цитата
я ввожу кол-во записей,затем по порядку все поля записи.
затем всё это по идее должно писаться в бинарный файл.
Если бы ты не стала переделывать то, что было приведено в посте №12 (я о функции
iostream& write(iostream &io, const TNotebook &note)
), оно даже и записывалось бы в файл... А так - у тебя ничего не пишется, файл note.bin остается пустым...

Второе: ДАЖЕ если ты запишешь в файл всю информацию, введенную в начале, что должно происходить потом? Сортировка, хорошо... Дальше? Запись данных, удовлетворяющих определенному критерию, в тот же файл? А что с ПРЕЖНИМИ данными? Новые же будут добавляться, так реализована функция write...

Выходов 2... Или после сортировки стереть все, что было из файла note.bin, и потом записывать только то, что удовлетворяет критерию, или работать с 2-мя файлами: в одном - полная информация, во втором отфильтрованная...

Учти также, что при последовательных запусках программы содержимое твоего файла будет накапливаться (из него ничего нигде не удаляется), так что нужно либо при старте программы спрашивать, что делать (удалять старую информацию/не удалять), либо делать что-то другое, но не оставлять это просто так...

Автор: Tribunal 12.11.2006 16:16

получается нужна полная функция...хорошо,так и сделаем...

дело в том,что в задании у меня сказано,что нужно дописать результаты в конец файла.
только вот действительно нет смысла в этом.ведь потом когда я допустим буду выводить содержимое файла на экран,будет выводится всё скопом,что не есть хорошо.
мне кажется ,что всё же стоит очищать файл и писать туда эл-ты структуры,соответствующие критерию.
правда,я не знаю как это делается unsure.gif

Автор: Алена 12.11.2006 16:40

Цитата
стоит очищать файл и писать туда эл-ты структуры,соответствующие критерию.
правда,я не знаю как это делается
Вот так:
    bin.close();
bin.open("note.bin", ios::in|ios::out|ios::binary|ios::trunc);
перед сортировкой... Но тогда у тебя совершенно пропадает смысл вообще записывать ВСЕ данные в файл. Они, конечно, будут записаны, только тут же удалятся, и перепишутся отфильтрованными данными. Лучше просто читай изначально в массив (без
write(bin,notebook[i]);
), а уже то, что подходит под критерий записывай в файл...

Автор: Tribunal 12.11.2006 17:09

решила я всё-таки не стирать ничего из файла.
а при выводе когда i=кол-ву изначальных записей,выводить слово result,
а потом отсортированную инф-ию.
НО на экран у меня выводится полный бред=(куча ноликов...а того,что нужно нет.
что же делать?

#include <iostream.h>
#include <fstream.h>

typedef struct tagT
{
int disp_res_x;
int disp_res_y;

int f;
float d;
float hdd;
char mode [20];
float price;
}T;

T notebook[20];

istream& read(istream &in, T &notebook)
{
return in.read((char*)&notebook, sizeof(notebook));
}

template <class T> iostream& write(iostream &io, T)
{
union
{
unsigned value;
char buf[2];
} size = {0};

io.seekg(0, ios::beg);
io.read(size.buf, sizeof(size.buf));
io.clear();

++size.value;
io.seekp(0, ios::beg);
io.write(size.buf, sizeof(size.buf));

io.seekp(0, ios::end);
io.write((const char*)&notebook, sizeof(notebook));
return io;
}

int n;


int main()
{
fstream bin("note.bin", ios::in|ios::out|ios::binary);
bin.close();
bin.open("note.bin", ios::in|ios::out|ios::binary|ios::trunc);


cout << "Number of notes:";cin >> n;
write(bin,n);
for(int i = 0; i < n; i++)
{
cout << "Note#" << i+1;
cout << "name:";cin >> notebook[i].mode;
cout << "chastota:";cin >> notebook[i].f;
cout << "diagonal:";cin >> notebook[i].d;
cout << "hdd:";cin >> notebook[i].hdd;
cout << "displey resolution:";cin >> notebook[i].disp_res_x;
cout << "x";cin >> notebook[i].disp_res_y;
cout << "price:";cin >> notebook[i].price;
write(bin,notebook[i]);
}



T buf;
for (int i=0;i<n;i++)
for (int j=n-1;j>=i+1;j--)
{
if (notebook[j-1].price > notebook[j].price)
{
memmove (&buf, &notebook[j-1], sizeof(T));
memmove (&notebook[j-1],&notebook[j], sizeof(T));
memmove (&notebook[j], &buf, sizeof(T));
};
};

bin.seekg(2, ios::beg);
for (int i=0;i<n;i++)
{
if (notebook[i].f>120) write(bin,notebook[i]);
}

bin.seekg(2, ios::beg);
int i;
i=0;
while (read(bin,notebook[i]))
{
cout << notebook[i].mode <<"--"<< notebook[i].f <<"--"<< notebook[i].d <<
"--"<< notebook[i].hdd <<"--"<< notebook[i].disp_res_x<<"--"<<
notebook[i].disp_res_y <<"--"<< notebook[i].price<<"--"<< endl;

i++;
if (i==n) cout << "result:" <<endl;
};

}

Автор: Алена 12.11.2006 17:38

Да что же тебя так тянет КАЖДЫЙ РАЗ менять что-то кардинально в программе??? Формат вывода зачем изменила? Чего теперь удивляешься, что одни циферки? Ты ж их и выводишь!!! Вот раньше был нормальный вывод...

Зачем тебе понадобилось добавить template <class T> перед описанием функции write? Чтоб программа перестала соответствовать Стандарту? Убери это... Вот так должен выглядеть заголовок write:

iostream& write(iostream &io, const T &notebook)
{
...
}
Чтобы теперь программа компилировалась, нужно убрать строку

    cout << "Number of notes:";cin >> n;
// write(bin,n); // <--- Вот эту
(запись размера происходит автоматически при вызове write)

А чтобы программа стала работать правильно -

    streampos mark = bin.tellg(); // Запоминаем позицию, в которой находились ДО фильтрации
bin.seekg(2, ios::beg);
for (int i=0;i<n;i++) // Фильтруем файл
{
if (notebook[i].f>120) write(bin,notebook[i]);
}

// И восстанавливаем ту позицию, которую сохранили... Теперь
// будут читаться только данные, удовлетворяющие твоему условию...
bin.seekg(mark, ios::beg);

i=0;
while (read(bin,notebook[i]))
{
cout << "Note#" << i+1;
cout << "name:" << notebook[i].mode << endl;
cout << "chastota:" << notebook[i].f << endl;
cout << "diagonal:" << notebook[i].d << endl;
cout << "hdd:" << notebook[i].hdd << endl;
cout << "displey resolution:" << notebook[i].disp_res_x;
cout << "x" << notebook[i].disp_res_y << endl;
cout << "price:" << notebook[i].price << endl;
i++;
};

Автор: Tribunal 12.11.2006 17:50

огромное спасибо за уделённое время и помощь! give_rose.gif