Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
#1

Подскажите как записать массив структур в файл - C++

07.02.2011, 17:39. Просмотров 1954. Ответов 3
Метки нет (Все метки)

Написал програмку, которая копирует желаемый прямоугольник(массив символов с атрибутами) в указанное место на экарн.
Программа работает так как задуманно.
В функции ReadRectSurface я использую несколько раз оператор new и ниразу delite. Подскажите пожайлуста в каком месте я должен вставить операторы delite и почему именно в том месте.
Подскажите как записать массив структур FRAGMENT в файл и затем прочитать его из файла.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <windows.h>
#include <iostream>
using namespace std;
 
// максимальный LIMIT 13300
const int LIMIT = 20;    // копируемый прямоугольник, ширина * высота = LIMIT
 
//стуктура предназначена для хранения части поверхности или всей поверхности если ее размер не превышает LIMIT
typedef struct _FRAGMENT {
    int counter;                // счетчик, показывает сколько фрагментов находится после текущего
    COORD dwBufferSize;         // размер фрагмента
    CHAR_INFO *lpBuffer;        // буфер данных, здесь хранятся символы
} FRAGMENT, *PFRAGMENT;
 
// ReadRectSurface считывает прямоугольник из указанной поверхности и заносит его в масив фрагментов
// если ширина копируемого прямоугольника превысить LIMIT, выдаст ошибку
// 1) HANDLE поверхности
// 2) указатель на масив FRAGMENT
// 3) копируемый прямоугольник
//-------------------------------------------------------------------------------------
FRAGMENT* ReadRectSurface(HANDLE hSurface, SMALL_RECT lpReadRegion, FRAGMENT *pBuffer)
{    
    //вычисляем размер копируемого прямоугольника
    COORD RegionSize;
    RegionSize.X = lpReadRegion.Right - lpReadRegion.Left + 1;    //ширина прямоуголника
    RegionSize.Y = lpReadRegion.Bottom - lpReadRegion.Top + 1;    //длина прямоугольника
 
    if(RegionSize.X > LIMIT)
    {
        {MessageBox(NULL, "ERROR RegionSize.X > LIMIT", "Console Error", MB_OK); return 0;}
        return 0;
    }
    
    else if (RegionSize.X * RegionSize.Y < LIMIT)//то в массив заносим только одит фрагмент
    {
        pBuffer = new FRAGMENT[1];
        pBuffer->counter = 1;
        pBuffer->dwBufferSize.X = RegionSize.X;
        pBuffer->dwBufferSize.Y = RegionSize.Y;        
        pBuffer->lpBuffer = new CHAR_INFO [RegionSize.X * RegionSize.Y];
        // Верхняя левая ячейка назначения временного буфера равна строка 0, колонка 0.
        COORD coordBufCoord = {0,0};
        // Скопируем блок из поверхности во временный буфер.
        if(!ReadConsoleOutput(
                                hSurface,            // HANDLE поверхности из которой читаем
                                pBuffer->lpBuffer,    // буфер, в который копируем
                                RegionSize,           // размер копируемого прямоугольника 
                                coordBufCoord,      // верхняя левая ячейка назначения
                                &lpReadRegion))     // источниковый прямоугольник экранного буфера        
            {MessageBox(NULL, "ERROR in ReadConsoleOutput", "Console Error", MB_OK); return 0;}                        
        return pBuffer;
    }
 
    else
    {
        pBuffer = new FRAGMENT[RegionSize.Y];        
        for(int i = 0; i < RegionSize.Y; i++)
        {
            pBuffer[i].counter = RegionSize.Y - i;
            pBuffer[i].dwBufferSize.X = RegionSize.X;
            pBuffer[i].dwBufferSize.Y = 1;            
            pBuffer[i].lpBuffer = new CHAR_INFO[RegionSize.X];
 
            // Верхняя левая ячейка назначения временного буфера равна строка 0, колонка 0.
            COORD coordBufCoord = {0,0};
 
            // Скопируем блок из поверхности во временный буфер.
            // Установим прямоугольник источника.
            SMALL_RECT srctReadRect;
            srctReadRect.Top = lpReadRegion.Top + i;    // 
            srctReadRect.Left = lpReadRegion.Left;
            srctReadRect.Bottom = lpReadRegion.Top + i; // 
            srctReadRect.Right = lpReadRegion.Right;            
            
            if(!ReadConsoleOutput(
                                    hSurface,                    // HANDLE поверхности из которой читаем
                                    pBuffer[i].lpBuffer,        // буфер, в который копируем
                                    pBuffer[i].dwBufferSize,       // количество колонок/строк
                                    coordBufCoord,              // верхняя левая ячейка назначения
                                    &srctReadRect))             // источниковый прямоугольник экранного буфера            
                {MessageBox(NULL, "ERROR in ReadConsoleOutput", "Console Error", MB_OK); return 0;}
        }
        return pBuffer;
    }
}
//-------------------------------------------------------------------------------------------------------------
bool WriteRectSurface(HANDLE hSurface, COORD position, FRAGMENT *pBuffer)
{
    // Верхняя левая ячейка назначения временного буфера равна строка 0, колонка 0.
    COORD coordBufCoord = {0,0};
    if(!pBuffer)
        {MessageBox(NULL, "ERROR in WriteRectSurface, pBuffer = NULL", "Console Error", MB_OK); return false;}    
    else if(pBuffer->counter == 0)
        {MessageBox(NULL, "ERROR in WriteRectSurface, pBuffer->counter == 0", "Console Error", MB_OK); return false;}
    else if(pBuffer->counter == 1)
    {        
        // Установим прямоугольник назначения.
        SMALL_RECT srctWriteRect;
        srctWriteRect.Top = position.Y;    // верхний левый: строчка 0, колонка 0
        srctWriteRect.Left = position.X;
        srctWriteRect.Bottom = position.Y + pBuffer->dwBufferSize.Y - 1; // нижний правый: строчка 1, колонка 79
        srctWriteRect.Right = position.X + pBuffer->dwBufferSize.X - 1;
 
        if(!WriteConsoleOutput(
                                hSurface,     // экранный буфер, в который будем записывать
                                pBuffer->lpBuffer,            // буфер, из которого копируем
                                pBuffer->dwBufferSize,         // размер колонки/строки chiBuffer
                                coordBufCoord,        // верхняя левая ячейка источника в chiBuffer
                                &srctWriteRect))      // прямоугольник назначения экранного буфера
            {MessageBox(NULL, "ERROR in WriteConsoleOutput", "Console Error", MB_OK); return false;}
        return true;
    }
    else 
    {
        for(int i = 0; i < pBuffer->counter; i++)
        {
            // Установим прямоугольник назначения.
            SMALL_RECT srctWriteRect;
            srctWriteRect.Top = position.Y + i;    
            srctWriteRect.Left = position.X;
            srctWriteRect.Bottom = position.Y + i; 
            srctWriteRect.Right = position.X + pBuffer->dwBufferSize.X - 1;
 
            if(!WriteConsoleOutput(
                                hSurface,     // экранный буфер, в который будем записывать
                                pBuffer[i].lpBuffer,            // буфер, из которого копируем
                                pBuffer->dwBufferSize,         // размер колонки/строки chiBuffer
                                coordBufCoord,        // верхняя левая ячейка источника в chiBuffer
                                &srctWriteRect))      // прямоугольник назначения экранного буфера
            {MessageBox(NULL, "ERROR in WriteConsoleOutput", "Console Error", MB_OK); return false;}            
        }
        return true;
    }
}
//---------------------------------------------------------------------------------------------------------------
int main()
{        
    for(int i = 0; i< 10;i++) //чет-то заполняем экрань
    cout<<i<<"ABCDEFGHIKLMNOPQRSTUVWXYZ"<<endl;
 
    //Меня интересует, как записать массив структур FRAGMENT в файл и затем прочитать из файла
    FRAGMENT *mf = 0;    //указатель на массив структур FRAGMENT
 
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    SMALL_RECT ReadRegion1 = {0,0,9,9};    
 
    mf = ReadRectSurface(hStdout,ReadRegion1, mf);
    if(!mf)
        cout<<"Error"<<endl;
    if(mf->counter == 0)
    {
        cout<<"Create single fragment"<<endl;
        cout<<"mf->dwBufferSize.X - "<<mf->dwBufferSize.X<<endl;
        cout<<"mf->dwBufferSize.Y - "<<mf->dwBufferSize.Y<<endl;
    }
    else
    {
        cout<<"Create "<<mf->counter<<" fragments"<<endl;
        for(int i = 0; i< mf->counter; i++)
            cout<<"mf["<<i<<"].counter"<<mf[i].counter<<endl;        
    }
 
    //указываем позицию куда вывести скопированый прямоугольник (точка вставки, верний левй угол) 
    COORD poit = {40,0};
    if(!WriteRectSurface(hStdout,poit,mf))
        cout<<"Error in WriteRectSurface"<<endl;    
 
    getchar();
    return 0;
}
Добавлено через 10 минут
Если я правильно понимаю, масиив который я создал, я могу использовать еще несколько раз для вставки, поэтому его нужно удалять, когда он мне уже точно не потребуется, ну например перед выходом из программы.

Добавлено через 27 минут
Может как-то так записывать мою структуру в файл?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//запись структуры в бинарный файл
    char fileName[80];
    cout<<"Please enter the file name: ";
    cin>> fileName;
    ofstream fout(fileName, ios::binary);
    if(!fout)
    {
        cout<<"Unable to open " << fileName<<" for writing. \n";
        return (1);
    }
    for(int i=0; i<mf->counter; i++)
    {
        fout.write((char*)mf[i].counter, sizeof mf[i].counter);
        fout.write((char*)&mf[i].dwBufferSize , sizeof mf[i].dwBufferSize);
        fout.write((char*)mf[i].lpBuffer, mf[i].dwBufferSize.X * mf[i].dwBufferSize.Y * sizeof mf[i].lpBuffer);
    }
    fout.close();
Добавлено через 34 минуты
И как-то так считывать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//чтение структуры из бинарного файла
    ifstream fin(fileName, ios::binary);
    if(!fin)
    {
        cout<<"Unable to open"<<fileName<<" for reading.\n";
        return (1);
    }
    FRAGMENT *new_mf = 0;
    fin.read((char*)new_mf->counter, sizeof new_mf->counter);
    for(int i = 0; i<new_mf->counter; i++)
    {
        fin.read((char*)new_mf[i].counter, sizeof new_mf[i].counter);
        fin.read((char*)&new_mf[i].dwBufferSize, sizeof new_mf[i].dwBufferSize);
        fin.read((char*)new_mf[i].lpBuffer, mf[i].dwBufferSize.X * mf[i].dwBufferSize.Y * sizeof new_mf[i].lpBuffer);
    }
    fin.close();
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.02.2011, 17:39     Подскажите как записать массив структур в файл
Посмотрите здесь:

Как записать массив структур в файл - C++
Ребят всем привет у меня такой вопрос как мне записать #include &lt;iostream&gt; #include &lt;windows.h&gt; #include &lt;iomanip&gt; #include...

Записать массив структур в бинарный файл - C++
Собственно программа, которая записывает\считывает масс структур в бинарный файл... проблема следующая, при выводе выводится только 1-ая...

Заполнить массив структур сканеров и записать его в бинарный файл - C++
Здравствуйте! Новый день - новая проблема. Не могу справиться с заданием семинара, помогите пожалуйста. Семинар из практикума...

как записать в файл значение елементов масива структур? - C++
Записать в файл значение елементов масива структур и считать их из файла в другой масив.

Как записать данные из файла в массив структур? - C++
В коде я ввожу данные и их записывает в файл, помогите пожалуйста записать данные из файла в массив структур #include &lt;conio.h&gt; ...

Ввести данные в файл, и записать данные с файла в массив структур - C++
Ввести все данные в файл, и записать данные с файла в структуру. Помогите ввести и вывести структуру из файла. Допускается - и желательно...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
accept
4821 / 3241 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
08.02.2011, 09:28     Подскажите как записать массив структур в файл #2
надо в main() после записи вызвать функцию освобождения
для этого нужно знать, сколько элементов в выделенном массиве
всё выделенное должно быть освобождено
у тебя там вроде есть инфа о количестве элементов массива, но она неправильно сделана, так как каждый узел хранит ненужное значение, можно было сделать количество элементов снаружи

C++
1
2
3
4
struct Fragment {
    Coord dwBufferSize;         // размер фрагмента
    Char_info *lpBuffer;        // буфер данных, здесь хранятся символы
};
C++
1
2
3
4
struct Box {
    Fragment *ptr;
    int n;
};
Цитата Сообщение от QWAN
Может как-то так записывать мою структуру в файл?
твои структуры содержат указатели, поэтому данные из них не будут сохраняться (только адрес, хранящийся в указателе)
даже если у тебя структуры были бы без указателей, способ прямой записи/чтения был бы гарантирован только в пределах одного компа
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
08.02.2011, 10:51  [ТС]     Подскажите как записать массив структур в файл #3
accept, скажи пожайлуста в какую сторону хотябы искать как записать то что я копирую в массив.

Цитата Сообщение от accept Посмотреть сообщение
даже если у тебя структуры были бы без указателей, способ прямой записи/чтения был бы гарантирован только в пределах одного компа
Ты хотеш сказать что на разных компъютерах может отличатся размер моей структуры?

Добавлено через 38 минут

Добавлено через 23 секунды
Скорее всего для того чтобы сохранить указанный прямоугольник мне нужно создать дополнительный экранный буфер консоли по размерам копируемого прямоугольника, скопировать туда мой прямоугольник. Идалее вызвать функцию типа ReadFile.
Но судя по тому как она описывается http://www.vsokovikov.narod.ru/New_M...n_readfile.htm
Я сохраню в файл только символы без цвета и фона.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.02.2011, 08:37     Подскажите как записать массив структур в файл
Еще ссылки по теме:

Подскажите пожалуйста как заполнить весь массив структур структурой p1 - C++
Подскажите пожалуйста как заполнить весь массив структур структурой p1; { struct Univer{ char fam; char kaf; char...

Файл: Записать список структур в файл - C++
мне надо Массив записать в ФАЙЛ!!!!!! по заданию есть прога, её надо подредактировать, но это не суть главное чтоб там была работа с...

записать масив структур в файл - C++
Люди помогите написать код, записи структуры в файл!!!!!!! FILE* file = fopen(&quot;Myt!!.txt&quot;, &quot;w&quot;); for (i=0;i&lt;n;i++) { ...

Есть файл с данными . Как переписать эти данные в массив структур? - C++
Допустим есть файл 1.txt с данными: 123 789 456 733 Нужно из файла переписать данные в массив структур. Например , есть...

Подскажите кто-нибудь, как записать квадратную динамическую матрицу в файл??? - C++
Подскажите кто-нибудь, как записать квадратную динамическую матрицу в файл??? Вот я её заполнил: #include&lt;iostream&gt; #include&lt;stdio.h&gt;...

Как объявить динамический массив структур, и как выглядит обращение к полям структур по указателю? - C++
Ребята подскажите как объявить динамический массив структур, и как выглядит обращение к полям структур по указателю.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
accept
4821 / 3241 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
09.02.2011, 08:37     Подскажите как записать массив структур в файл #4
Цитата Сообщение от QWAN
Ты хотеш сказать что на разных компъютерах может отличатся размер моей структуры?
может много чего различаться: выравнивание внутри структур, направление байтов в переменных, размеры базовых типов
если ты сохраняешь файл на одном компьютере, то на другом компе его нельзя загружать, может исказиться
fread(), fwrite() со структурами можно применять в пределах одного компа

нужно сохранять структуру по частям и загружать по частям
C++
1
2
3
4
struct Fragment {
    Coord dwBufferSize;         // размер фрагмента
    Char_info *lpBuffer;        // буфер данных, здесь хранятся символы
};
запиши это в виде текста в файл

1ая запись
первое значение записываешь в виде числа
дальше через разделитель записываешь содержимое буфера
дальше конец записи

2ая запись
первое значение записываешь в виде числа
дальше через разделитель записываешь содержимое буфера
дальше конец записи

при считывании можно читать записи пока они читаются, а можно в начале файла записать число записей, чтобы определить цикл чтения записей

Код
3
12 abcdeabcdeab;
3 abc;
8 abcdeabc;
Yandex
Объявления
09.02.2011, 08:37     Подскажите как записать массив структур в файл
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru