Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
45 / 25 / 16
Регистрация: 14.04.2011
Сообщений: 623

Как прочитать из файла несколько символов и удалить

21.09.2014, 16:03. Показов 1788. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть файл неизвестного мне размера, он может быть безобидный 2кб, а может быть и 2Гб, 1 - 2 раза файл такого размера в память и выскакивает исключение "Out of memory".

В самом начале файла есть вот такое выражение: "{FUN:6:1}" где цифры могут быть двузначными и больше.
после этого выражение идет само содержимое файла, задача прочитать эти 2 цифры и удалить выражение из файла, не занося этот файл целиком в память.

Засунул в файл выражение выше и решил поэкспериментировать, длина его = 10, но он прочитал почему то до 4:
C++
1
#define SIZE_BUFF_READ 2
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
FILE * pFile;
char *buffer[SIZE_BUFF_READ];
AnsiString result;
int len;
 
pFile = fopen ( "2.mp4" , "rb" );
if (pFile==NULL) exit (1);
 
for (int i = 1;;i++)
{
    for (int f = 0; f <= result.Length(); f++)
    {
        if (result.SubString(f,1) == "}")
        {
            len = i;
            goto end_fread;
        }
    }
    fseek (pFile ,SIZE_BUFF_READ*i, SEEK_SET);
    if (fread (buffer,1,SIZE_BUFF_READ*i,pFile) <= 0)   break;
    result += (char *)buffer;
    //free (buffer);
}
end_fread:
 
MessageBoxW(NULL,result.c_str(),"file",MB_OK);
В окне выводит такой вывод (см приложение)
и len = 4, а должен был быть равен 10.
Почему так получилось?

И как мне теперь удалить это выражение, опять же не занося весь файл в память?
Есть предположение что мне теперь надо просто перезаписать его читая по тем же к примеру 1024 байтам игнорируя это выражение.
Само выражение должно быть в самом начале файла, но зная юзера он может поиграться и перенести его в середину файла...
Изображения
 
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.09.2014, 16:03
Ответы с готовыми решениями:

Удалить из каждой строки файла первые несколько символов
Дано целое число K и текстовый файл. Удалить из каждой строки файла первые K символов (если длина строки меньше K, то удалить из нее все...

Как прочитать числа из файла в несколько numericupdown?
Есть файл, в котором записано: Число1 Число2 Число3 Число4 Число5 Число6 При нажатии кнопки из этого файла числа должны...

Как прочитать несколько байт из файла с n-го бита
Требуется считать байты из файла заданным смещением; смещение задается в БИТАХ; Например: c 3-го бита 8-го байта прочитать 21 байт;

3
45 / 25 / 16
Регистрация: 14.04.2011
Сообщений: 623
21.09.2014, 20:17  [ТС]
Прочитал все выражение:


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
FILE *pFile;
char *buffer;
AnsiString result;
 
pFile = fopen ( "1" , "rb" );
if (pFile==NULL) exit (1);
 
for (int i = 1;;i++)
{
    for (int f = 0; f < result.Length(); f++)
    {
        if (result.SubString(f,1) == "}")
        {
            result = result.SubString(0,f);
            goto end_fread;
        }
    }
    fseek (pFile ,SIZE_BUFF_READ*i-SIZE_BUFF_READ, SEEK_SET);
    rewind (pFile);
    buffer = (char*) malloc (sizeof(char)*(SIZE_BUFF_READ*i));
    if (fread (buffer,1,SIZE_BUFF_READ*i,pFile) <= 0)   break;
    result = (char *)buffer;
    free (buffer);
}
end_fread:
 
MessageBoxA(NULL,result.c_str(),"file",MB_OK);
Теперь буду разбираться с удалением этого выражения

Добавлено через 43 минуты
Не получается что-то

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fseek (pFile,0,SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
 
for (int i = result.Length(); i <= lSize; i += 32)
{
    if (i > lSize)  i = i - lSize;
 
    fseek (pFile ,i, SEEK_SET);
    rewind(pFile);
    buffer = (char*) malloc (sizeof(char)*i);
    fread (buffer,1,i,pFile);
 
    fseek (pFile ,i-result.Length(), SEEK_SET);
    fread (buffer,1,i,pFile);
    fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
    free (buffer);
}
free (buffer);
fclose (pFile);
В итоге он из такого файла:
Code
1
2
3
4
5
6
{FUN:6:231}FILEFILEFILEFILE
FILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILE
FILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILEFILE
FILEFILEFILEFILEFILEFILEFILEFILE
FILEFILEFILEFILEFILEFILEFILEFILE
FILEFILEFILEFILE
Сделал вот такой:
Code
1
2
3
4
5
6
{FUN:6:231}FILEFILEFILEFILE
FIL{FUNEFILEFILEFILEFILEFILEFILEFIL{FUNEFILEFILEFILEFILEFILEFILE
F{FUNILEFILEFILEFILEFILEFILEFILEF{FUNILEFILEFILE
FILEFILEFILEFIL{FUNEFILEFILEFILE
FILEFILEFILEF{FUNILEFILEFILEFILE
FILEFILEFILEFILE{FUN{FUN{FUN
А нужно всего-то убрать "{FUN:6:231}"
длина которой известна в result.Length()

Как сделать?

Добавлено через 1 час 39 минут
Поковырялся и пришел к такому виду:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fseek (pFile,0,SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
 
for (int i = 1; i <= lSize; i += 32)
{
    if (i > lSize)  i = i - lSize;
 
    fseek (pFile ,i-1+result.Length(), SEEK_SET );
    buffer = (char*) malloc (sizeof(char)*(i*32));
    fread (buffer,1,(i*32),pFile);
 
    MessageBoxA(NULL,(char*)buffer,"write",MB_OK);
    rewind (pFile);
 
    fseek (pFile ,i-1+result.Length(), SEEK_SET);
    fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
    free (buffer);
}
free (buffer);
fclose (pFile);
Читать он начинает с правильного места, но после записи все остается на своем месте, только в конце какая то каша из символов получается
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
22.09.2014, 07:01
Лучший ответ Сообщение было отмечено Путин как решение

Решение

Путин, Вы бы сначала на строках такой функционал попробывали сделать, а потом бы к файлу перешли. То есть, примерно так:
Задача
Есть строка "{FUN:6:231}FILEFILEFILEFILE" длиной 27 символов, нужно эту строку преобразовать в строку "FILEFILEFILEFILE" длиной 16 символов. Начальная строка находится в массиве char[28], конечная должна быть в массиве char[17]. Под новую строку нельзя создавать новый массив - нужно менять старый. Указатель на строку менять нельзя (то есть нельзя сделать str += 11, чтобы обрезалось начало строки).
Если же главным является не забить оперативу, то можно сделать так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
 
int main(int argc, char* argv[])
{
        FILE* sourceFile = fopen("1", "rb");
        FILE* destFile = fopen("~1", "wb");
        int c;
 
        while(fgetc(sourceFile) != "}");
 
        while((c = fgetc(sourceFile)) != EOF)
            fputc(c, destFile);
 
        fclose(sourceFile);
        fclose(destFile);
 
        remove("1");
        rename("~1", "1");
 
        return 0;
}
Правда для этого варианта, в случае файла в 2ГБ нужно еще 2ГБ свободного места на винте. Зато такая программулина стабильно отжирала всего 872 КБ оперативы на 2-х гиговом файла (скомпилирована в BCB6).

PS:Почему вы с C-шными задачами залезаете не просто в раздел C++, а в раздел C++ Builder? И в C++ и в C++ Builder есть иные методы работы с файлами, которые являются более приоритетными. По данным функциям наиболее квалифицированный ответ вы сможете получить в разделе C.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
22.09.2014, 21:22
Цитата Сообщение от kodv Посмотреть сообщение
Почему вы с C-шными задачами залезаете не просто в раздел C++, а в раздел C++ Builder? И в C++ и в C++ Builder есть иные методы работы с файлами, которые являются более приоритетными.
Ну, дык, и подсказал бы методы эти, что ж так категорично-то?.. Может, человек только этого и ждет?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.09.2014, 21:22
Помогаю со студенческими работами здесь

Как прочитать 80 строк по 80 символов из файла?
Никогда не было проблем с языками программирования, но вот момент настал. Как прочитать 80 строк по 80 символов из файла? как из файла...

Как прочитать первые 15 символов огромного файла
Всем добрый день. Собственно вопрос в теме, файл очень большой, и что бы не грузить его весь, хотелось бы понять как можно прочитать...

Как прочитать первую строку из файла а остальной текст повторить несколько раз?
Я новичок в этом деле, прошу не осуждать. Помогите разобраться. Задание такое: Программа должна начать читать запись шоколада с...

Прочитать несколько секунд wav файла в массив
Есть win32 проект в Студии. Задача - запросить диалог выбора wav файла, проверить что это wav файл, прочитать его хедер, взять оттуда...

Как задать маску для файла, содержащего несколько любых символов подряд?
Всем привет! Подскажите, пожалуйста, или киньте ссылкой - как правильно задавать точные маски для файлов, переменных и т.п.? ...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru