Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с памятью 
:(
    Опции темы
grindbastard
Дата 23.9.2013, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.5.2013

Репутация: нет
Всего: нет



Доброго всем времени суток!
Ребят помогите разобраться. 
Задание:
Цитата

Текстовый редактор. Вводится текст в окне, этот текст записывается в выходной файл. Размер файла должен динамически увеличиваться в зависимости от размера вводимого текста.
Порядок работы программы:
Создание выходного файла фиксированного размера. Отображение файла в память
При вводе текста, автоматически сохранять его в файле (за это отвечает отображение файла в память)
Если размер текста превышает размер файла, выделять дополнительную область памяти фиксированного размера
Выход осуществляется закрытием окна приложения


Код получился следующий: 
Цитата

#include "stdafx.h"
#include "Windows.h"
#include <tchar.h>
#include <iostream>
#include <fstream>
using namespace std;


DWORD fileSizeLow;
DWORD fileSizeHigh;
int ch;
HANDLE hFile;
HANDLE hFileMapping;
int size = 50;
char *text = new char[size];

int _tmain(int argc, _TCHAR* argv[])
{
    while(true)
    {
    cout<<"**********************"<<endl;
    cout<<"1.Begin the programm"<<endl;
    cout<<"2.Exit"<<endl;
    cout<<"**********************"<<endl;
    cout<<"Your choose - > ";
    cin>>ch;
    switch(ch)
    {
  case 1:
    {  hFile = CreateFile(_T("1.txt"),
          GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_WRITE,NULL,
          CREATE_ALWAYS,
          FILE_ATTRIBUTE_NORMAL,NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,256,0);
    PVOID pvFile = MapViewOfFile(hFileMapping,FILE_MAP_WRITE,0,0,256);
    
    cout << "File put on the memory!"<<endl<<endl;
    cout << "Enter text into file"<<endl;
    cout << "Your text: "<<endl;
    cin >> text;
    

    fileSizeLow=GetFileSize(_T("1.txt"),&fileSizeHigh);


    strcpy((char*)pvFile,text);
    cout<<"This text put on the file 1.txt" << endl;


    UnmapViewOfFile(pvFile); 
    CloseHandle(hFileMapping); 
    CloseHandle(hFile);
    break;
    }
    
  case 2:
    cout<<"Good bye!"<<endl;  return 0;// 0;    
    }
    }
    return 0;
}




Вопрос в следующем:
 как правильно реализовать сие - "Если размер текста превышает размер файла, выделять дополнительную область памяти
 фиксированного размера" 

PM MAIL   Вверх
feodorv
Дата 24.9.2013, 06:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(grindbastard @  24.9.2013,  00:42 Найти цитируемый пост)
как правильно реализовать сие - "Если размер текста превышает размер файла, выделять дополнительную область памяти фиксированного размера" 

Рискну предположить, что речь идёт об этом:
Цитата(grindbastard @  24.9.2013,  00:42 Найти цитируемый пост)
Размер файла должен динамически увеличиваться в зависимости от размера вводимого текста.

То есть при превышении лимита (текущего размера отображенного в память файла) необходимо старое отображение закрыть и открыть новое с увеличенным лимитом. И так далее.


Цитата(grindbastard @  24.9.2013,  00:42 Найти цитируемый пост)
   strcpy((char*)pvFile,text);

Таким образом Вы не дописываете текст в конец файла (отчего лимит и может исчерпаться), так Вы перезаписываете начало файла... И я бы не стал на каждом цикле переоткрывать файл и пересоздавать отображение, более того:
Цитата(grindbastard @  24.9.2013,  00:42 Найти цитируемый пост)
Выход осуществляется закрытием окна приложения

а Вы switch придумали, не нужен он.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
grindbastard
Дата 24.9.2013, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.5.2013

Репутация: нет
Всего: нет



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

Цитата

Таким образом Вы не дописываете текст в конец файла (отчего лимит и может
исчерпаться), так Вы перезаписываете начало файла... И я бы не стал на каждом
цикле переоткрывать файл и пересоздавать отображение, более того:

Выход осуществляется закрытием окна приложения



а каким образом тогда это все можно реализовать?
PM MAIL   Вверх
feodorv
Дата 24.9.2013, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(grindbastard @  24.9.2013,  10:15 Найти цитируемый пост)
хм,в соответствии с заданием при превышении необходимо выделять дополнительную память, а не закрывать отображение. т.е. отображение открыто,а уже к нему выделяется блок доп памяти. 

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


Цитата(grindbastard @  24.9.2013,  10:15 Найти цитируемый пост)
а каким образом тогда это все можно реализовать? 

Вы запоминаете позицию в отображении (офсет), где заканчивается ранее введённый текст. При добавлении нового текста Вы проверяете, хватает ли свободного пространства в файле. Если хватает, то просто добавляете, начиная с офсета, потом офсет корректируется на размер добавленного текста. Если места не хватает, то придётся переоткрывать отображения файла увеличенного размера (так, чтобы влез добавляемый текст). При этом уже введённый текст перекопировать не нужно, поскольку он уже содержится в файле, соответственно, и значение офсета остаётся прежним (при переоткрытии отображения). Затем добавляется текст, как в первом случае. Под конец делается flush, чтобы синхронизировать отображение с файлом на диске:
Код

Создание отображения файла размером N байт
Офсет инициализируется нулём

Цикл
  Ввод текста
  If не хватает места
    Вычисление нового размера отображения
    Переоткрытие отображения с новым размером
  Endif
  Добавление текста в отображение начиная с офсета
  Корректировка офсета на размер добавленного текста
  Синхронизация отображения с диском
Endцикла



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
grindbastard
  Дата 29.9.2013, 04:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.5.2013

Репутация: нет
Всего: нет



Не совсем понимаю как реализовать само условие в цикле (while (какое условие?))

И можно пример кода этого...а то чтот не моу понять....

Цитата

Цикл
  Ввод текста
  If не хватает места
    Вычисление нового размера отображения
    Переоткрытие отображения с новым размером
  Endif



PM MAIL   Вверх
feodorv
Дата 29.9.2013, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(grindbastard @  29.9.2013,  05:59 Найти цитируемый пост)
while (какое условие?)
Цитата(grindbastard @  24.9.2013,  00:42 Найти цитируемый пост)
    while(true)



Цитата(grindbastard @  29.9.2013,  05:59 Найти цитируемый пост)
И можно пример кода этого...а то чтот не моу понять....

Приблизительно так (и без юникода):
Код
const DWORD map_delta = 1024;

HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hFileMapping = NULL;
PVOID pvFile = NULL;

bool openMapping( DWORD size, bool isResizing)
{
    if( !isResizing &&
        (hFile = CreateFile( "1.txt", GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
          FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE )
    {
       // ругаемся
       return false;
    }

    if( isResizing )
    {
        UnmapViewOfFile(pvFile); 
        pvFile = NULL;
        CloseHandle(hFileMapping); 
        hFileMapping = NULL;
    }

    if( (hFileMapping = CreateFileMapping( hFile, NULL, PAGE_READWRITE, 0, size, 0)) == NULL )
    {
       // ругаемся
       return false;
    }

    if( (pvFile = MapViewOfFile( hFileMapping, FILE_MAP_WRITE, 0, 0, size)) == NULL )
    {
       // ругаемся
       return false;
    }

    return true;
}

...

// Создание отображения файла размером N байт
DWORD map_size = map_delta;
if( !openMapping( map_size, false) ) return -1;

// Офсет инициализируется нулём
DWORD offset = 0;

...

// Ввод текста
    cout << "Your text: "<< endl;
    char text[128];
    cin.getline( text, 128);
    if( !cin ) cin.clear();

// If не хватает места
    int length = strlen( text );
    if( offset + length + 2 > map_size )
    {

// Вычисление нового размера отображения
        map_size = offset + length + 2;
        map_size = ((map_size / map_delta) + (map_size % map_delta ? 1 : 0)) * map_delta;

// Переоткрытие отображения с новым размером
        if( !openMapping( map_size, true) ) return -1;
    }

    ...


2 дополнительных байта идут на перевод строки - '\r', '\n'.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1174 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.