Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.95/19: Рейтинг темы: голосов - 19, средняя оценка - 4.95
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6

Удаление строки из файла через сдвиги.

06.06.2011, 17:47. Показов 3821. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Прощу помочь с защитой лабы.
Есть файл тхт, в нем названия банков и значения по годам:
Банк 2000г 2001г
ВТБ; 35.4; 31.5
.....................
Банк Москвы; 0; 4.2

Что нужно:
Нам нужно удалить банки с значением 0 в один из годов. Решать эту задачу мы должны через сдвиги, так же мы не должны использовать буферные файлы или отдельные массивы строк.

Прикрепляю файл и ссылку на тему в которой решали саму лабу.
Вложения
Тип файла: txt fail.txt (489 байт, 20 просмотров)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.06.2011, 17:47
Ответы с готовыми решениями:

Удаление строки из txt файла, через какое-то время
на хостинге есть txt файл в нём 5 строк id1 - серийник 1 id2 - серийник 2 id3 - серийник 3 id4 - серийник 4 id5 - серийник 5

Удаление строки из файла\либо удаление самого файла.
День добрый, вот функция(используемые переменные объявленны ранее): void delete_cruise() { FILE *fout; ...

Удаление строки из файла, добавление строки в конец файла
Подскажите : Как удалить строку в txt файле в которой имеется слово "Zebra". А так же как добавить строку в тхт файл не удалив...

24
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
07.06.2011, 02:16  [ТС]
upd...
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
07.06.2011, 08:59
Решать эту задачу мы должны через сдвиги, так же мы не должны использовать буферные файлы или отдельные массивы строк.
Вот это совсем непонятно.
1. Обычно удаление из файла делается так: открывается исходный для чтения, новый для записи.
Пока исходный не кончился, читаем записи исходного, пишем в новый только те, которые удовлетворяют условию. В нашем случае это не равно 0.
Таким образом, ненужные записи просто пропускаются.
2. Если файл двоичный и размер записи известен и постоянен, то можно выполнять перезапись по месту, используя функцию вроде seek() - передвижение по записям.
Но в вашем случае файл-то текстовый! И размер строк в этом файле - разный!
0
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
07.06.2011, 10:26  [ТС]
ValeryLaptev, да, файл текстовый, и просили выполнить без 1 пункта.
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
07.06.2011, 10:39
Цитата Сообщение от IIIa66uMEM6eP Посмотреть сообщение
ValeryLaptev, да, файл текстовый, и просили выполнить без 1 пункта.
Тогда мне в голову приходит только один способ. Открыть текстовый файл как двоичный и читать побайтно. Но гемора с запоминанием позиций начала каждой строки - много. Для двоичных файлов с записями потому и реализовано передвижение по файлу, так как там размер записи известен и фиксирован. И легко посчитать сдвиг на нужную запись от начала. А в текстовом - все строки разной длины и приходится следить за концом записи - там есть символ '\n'. Но физически - это два байта:
0x0A0D или 0x0D0A - не помню в каком порядке.
0
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
07.06.2011, 11:06  [ТС]
ValeryLaptev, без гемора никуда. нельзя через темповский файл, нельзя массивы строк..
не могли бы подсказать что нибудь про побайтное чтение двоичного файла?
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
07.06.2011, 11:15
В С++ это метод read() для объекта типа fstream.
А вообще-то в моей книжке 14 глава: Библиотека ввода-вывода.

Не по теме:

Сейчас некогда - надо уходить. Вернусь - выдам инфу.

1
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
07.06.2011, 11:19  [ТС]
ValeryLaptev, я в книжке гляну. спс

Добавлено через 2 минуты
Ой.. у меня наверно не так книжка, эта - Экспрес курс С++
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
07.06.2011, 14:35
Цитата Сообщение от IIIa66uMEM6eP Посмотреть сообщение
ValeryLaptev, я в книжке гляну. спс

Добавлено через 2 минуты
Ой.. у меня наверно не так книжка, эта - Экспрес курс С++
Там тоже есть, но не так подробно. Поищи в сети дежавю-файл моей книжки по ООП.
0
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
07.06.2011, 19:26  [ТС]
ValeryLaptev, да... разбиратся много.. вообщем то мою задачу можно свести к тому, что бы считать файл по байтно и если найден код нуля - то ..., что сделать тогда? как затереть..
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
07.06.2011, 21:26
Не так просто.
1. Надо при чтении проверять байты 0d0a - это конец строки. И запоминать первую позицию после нее.
2. Потом читать байты до следующей 0d0a. Проверка на код нуля тебе не поможет, так как у тебя может быть число, например, такое - 100.05. Тут аж три нуля.
Мне в голову пришла мысль, что можно попробовать открыть два потока, связав их в одним файлом.. Один поток - текстовый, а второй - бинарный. Текстовый поток - чтобы вводить нормально данные и проверять на ноль. А бинарный - чтобы перемещаться по байтам этого файла.
Перемещение делается функциями seekg() - для чтения, и seekp() - для записи.
Все надо пробовать.
0
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
07.06.2011, 22:55  [ТС]
ValeryLaptev, идея понравилась, но с seek ни чего не делал раньше, да и с бинарными файлами тоже.. поможете?
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
07.06.2011, 23:21
Вот инфа.

Произвольный доступ
Как уже отмечалось, С++ позволяет выполнять позиционирование в любых потоках, кроме стандартных. Методы позиционирования приведены в табл. 14.5. Методы позиционирования различаются для входных и выходных потоков: для входных потоков (см. п.п. 27.6.1.3 в [1]) имена методов заканчиваются символом «g» (от слова get), для выходных (см. п.п. 27.6.2.4 в [1]) — символом «p» (от слова put).

Таблица 14.5. Методы позиционирования
Метод Описание
C++
1
2
3
4
5
6
pos_type tellg()    Получить текущую (абсолютную) позицию чтения
istream& seekg (pos_type p) Установить абсолютную позицию чтения
istream& seekg (off_type p, ios::seekdir s) Установить относительную позицию чтения
pos_type tellp()    Получить текущую (абсолютную) позицию записи
istream& seekp (pos_type p) Установить абсолютную позицию записи
istream& seekp (off_type p, ios::seekdir s) Установить относительную позицию записи
Функции tellp() и tellg() возвращают абсолютное смещение от начала потока. Символы потока нумеруются, как и индексы массива, начиная с нуля. Однако тип pos_type не является целым типом. Поэтому получать текущую позицию чтения в файловом потоке нужно так:
C++
1
ios::pos_type p = file.tellg();
Можно сохранить текущую позицию и в переменной типа streampos, например:
C++
1
streampos pos = file.tellp();
Переход к позиции, сохраненной в переменной pos, делается так:
C++
1
file.seekp(pos);
Несмотря на то, что тип значения позиции в потоке не является целым значением, целые константы можно использовать в качестве аргумента в методах установки позиции — выполняется преобразование по умолчанию. Символы в потоке нумеруются, начиная с нулевого, поэтому позиционирование в начало потока можно выполнить, например, так:
C++
1
file.seekg(0);
После этого опять можно будет прочитать первый символ потока.
Методы установки относительной позиции очень похожи на функцию fseek() из библиотеки <cstdio>. В классе ios_base определены следующие константы (см. п.п. 27.4.2.1.5 в [1]):
C++
1
2
3
static const seekdir beg,    // позиционирование от начала потока 
                     cur,    // позиционирование от текущей позиции
                     end;    // позиционирование от конца потока
Первый аргумент, который обычно задается целым числом (выполняется преобразование по умолчанию), является смещением (в символах) от указанной позиции. Положительное число означает смещение вперед — ближе к концу файла, отрицательное — смещение назад, к началу файла. Например, позиционироваться в конец файла можно так:
C++
1
file.seekg(0, ios::end);
При позиционировании нужно следить, чтобы позиция оставалась внутри файла. Попытка позиционироваться до начала потока или после конца приводит поток в состояние bad(). Небольшой пример показывает, как работает относительное позиционирование (листинг 14.22).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Листинг 14.22. Относительное позиционирование
int main()
{   fstream strm("c:/binfiles/oonumber2.bin",ios::binary|ios::in|ios::out);
    int a = 0;
    // читаем числа из файла и выводим 
    strm.seekg(2*sizeof(int), ios::beg);      // выставляемся от начала
    strm.read((char *)&a, sizeof(int));       // читаем
    cout << a << ' ' << '\n';
    // записываем новое число на ту же позицию
    a = 12021;
    strm.seekp(2*sizeof(int), ios::beg);      // выставляемся от начала
    strm.write((char *)&a, sizeof(int));      // записываем
    // возвращаемся, читаем снова и выводим
    strm.seekg(2*sizeof(int), ios::beg);      // выставляемся от начала
    strm.read((char *)&a, sizeof(int));       // опять читаем
    cout << a << ' ' << '\n';
    return EXIT_SUCCESS;
}
В примере открывается существующий (см. листинг 14.7) двоичный файл в режиме чтения/записи. Оба флага (ios::in|ios::out) задавать обязательно, иначе по умолчанию файловый поток открывается только для записи. Сначала читается третье от начала число, затем выполняется возврат в ту же позицию и записывается новое число. Результат можно наблюдать на экране.
C помощью методов позиционирования можно вычислить размер файла (листинг 14.23).
C++
1
2
3
4
5
6
7
8
Листинг 14.23. Функция, вычисляющая длину файла
long filesize(ifstream &stream)
{  streampos curpos = stream.tellg();    // сохраняем текущую позицию
   stream.seekg(0, ios::end);            // высталяемся на конец файла
   streampos last = stream.tellg();      // получаем позицию = длина
   stream.seekg(curpos);                 // возвращаем текущую позицию.
   return last;
}
Несмотря на то, что используются переменные типа streampos, в результате выполняется преобразование по умолчанию в тип long. Применять эту функцию можно как с двоичными файлами, так и с текстовыми, например:
C++
1
2
3
4
5
6
7
ifstream g;
g.open("c:/textfiles/result.files");
cout << filesize(g) << endl;
g.close();
g.open("c:/binfiles/bin2.bin", ios::binary);
cout << filesize(g) << endl;
g.close();
Сначала вычисляется длина текстового файла result.files, который образовался в каталоге textfiles в результате вызова функции includeFile() (см. листинг 14.5). Затем с помощью той же функции вычисляется длина двоичного файла из листинга 14.8.

Методы позиционирования облегчают обработку двоичных файлов, записанных любыми другими средствами, например, средствами языка Pascal. В С++, в отличие от языка программирования Pascal, отсутствуют типизированные файлы с записями (file of type). В языке Pascal такие файлы являются двоичными. Записи нумеруются, начиная с нуля, что обеспечивает прямой доступ к записи. Такие файлы в программе на языке Pascal по умолчанию открываются в режиме чтения/записи.
Мы вполне можем обработать такие файлы и обеспечить прямой доступ к записям по номерам средствами С++. Для этого нужно объявить в программе структуру, имеющую поля соответствующих типов, заданные в том же порядке, что в записи в программе на Pascale. Здесь нужно внимательно отнестись к проблеме выравнивания — структура в С++ должна иметь точно такой же размер, как и запись в Pascal. Далее нужно открыть файл как двоичный в режиме чтения/записи. Чтение из файла выполняется оператором
C++
1
strm.read((char *)&record, sizeof(T));
А запись выполняется оператором
C++
1
strm.write((char *)&record, sizeof(T));
Здесь sizeof(T) — размер структуры в С++, который должен совпадать с размером записи в Pascal.
Методы относительного позиционирования позволяют реализовать прямой доступ к записям этого двоичного файла. Например, позиционирование на k-ю запись для чтения выполняется оператором
C++
1
strm.seekg(k*sizeof(T), beg);
Если необходимо сместиться вперед от текущей позиции на одну запись вперед, можно воспользоваться любой из следующих инструкций:
C++
1
2
3
// эквивалентные вызовы seekg
stream.seekg(stream.tellg() + sizeof(T));     // абсолютная позиция
stream.seekg(sizeof(T), ios::cur);            // относительная позиция
Сместиться назад на одну запись можно так:
C++
1
2
stream.seekg(stream.tellg() - sizeof(T));     // абсолютная позиция
stream.seekg(-sizeof(T), ios::cur);           // относительная позиция
1
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
09.06.2011, 10:57  [ТС]
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
попробовать открыть два потока, связав их в одним файлом
как это сделать?

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Текстовый поток - чтобы вводить нормально данные и проверять на ноль
тоесть в этом случае 3 нуля не будет.

Все равно слабо представляю как это программно реализовать, мало с этим что то делал.
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
09.06.2011, 11:40
C++
1
2
fstream bin("name", ios::in|ios::out|ios::binary); // -- двоичный для перезаписи --
ifstream txt("name");                      // -- текстовый для ввода --
Я тоже подобного фокуса еще не пробовал, но насколько помню для чтения можно открывать файл одновременно несколько раз.
Но гемора тут все равно - много. Пробовать надо, фактически исследовательскую работу профодить, как будет вести себя файл и файловая система при таких наших действиях.

Из текстового файла вводить аналогично cin:
C++
1
txt >> var;
0
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
09.06.2011, 13:34  [ТС]
ValeryLaptev, вот так защита лабораторной)
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
09.06.2011, 13:38
Цитата Сообщение от IIIa66uMEM6eP Посмотреть сообщение
ValeryLaptev, вот так защита лабораторной)
Как обычно возможны два варианта...
1. Либо вы не совсем поняли препода в каких-то мелочах. Потому как перезапись ТРАДИЦИОННО исполняется только для двоичных файлов. Но никак не текстовых.
2. Либо препод совершенно не имеет реального опыта программирования. Отсюда и завихрительные требования. Ни один реальный программер не будет перезаписывать текстовый файл по месту.
0
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
09.06.2011, 13:40  [ТС]
2. точно два, ну он паскалист - незнаю может там это проще.
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
09.06.2011, 13:49
IIIa66uMEM6eP, тогда можно просто рассказать ему все наши соображения. Что строки разной длины, что надо запоминать позиции концов строк, что для перезаписи нужно открывать тот же файл в двоичном байтовом режиме и т.д. Мож впечатлится информацией, которую вам пришлось раскапывать...
0
заставил Бендера
 Аватар для IIIa66uMEM6eP
854 / 319 / 17
Регистрация: 05.12.2010
Сообщений: 1,707
Записей в блоге: 6
09.06.2011, 13:51  [ТС]
ValeryLaptev, иии)) скажет ну если все знаете - реализовывайте, приходите на защиту.. надо как то сформулировать - что бы ни вопросов ни придлогов) спасибо

Добавлено через 51 секунду
ValeryLaptev, вы же кажется тоже преподаватель?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.06.2011, 13:51
Помогаю со студенческими работами здесь

С 10 в 2 через битовые сдвиги
Помогите пожалуйста, как число перевести в 8 систему используя только циклы, сдвиги. Нельзя использовать Integrr. toOctal

Удаление строки через Combobox
Помогите решить задачку. Как удалить строку из таблицы при выборке из combobox а. Например: в моей таблице есть поля: ID, fio. Я добавил...

Удаление файла через 90 дней
Подкиньте код, который бы удалял файл к примеру через 90 дней

Удаление файла через cmds
пишу del c:\\name пишет что ошибка синтаксиса. (erase тоже самое что и del)

Удаление строки из файла
Удаляю строку из текстового файла string file_name =&quot;citate.txt&quot;; string readText =...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в конфигурации КА2. Данные берутся из регистра сведений, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru