argon bulletin board

Експертно търсене  

Новини:

Регистрирането на нови потребители е временно деактивирано.

Автор Тема: Файлове в Dev С++  (Прочетена 6075 пъти)

my_form

  • Неактивен Неактивен
  • Публикации: 45
Файлове в Dev С++
« -: 03.02.2010, 23:42:38 »

Къде мога да намеря разбираемо описание за обработка на файлове в Dev С++? Като казвам разбираемо имам предвид само най-важните неща, без много проверки. Особено ме интересува изтриване на елемент във файла.
За съжаление всеки източник си има свой стил и не е написан нито един учебник където има завършен вариант на програма за файлове.
Благодаря на всеки, който би споделил опита си.
Активен

antoniy

  • Управител
  • *
  • Неактивен Неактивен
  • Публикации: 723
    • http://antoniy.net/
Re:Файлове в Dev С++
« Отговор #1 -: 03.02.2010, 23:53:17 »

Dev  C++ ти е средата за разработка. Трябва да търсиш как се работи с файлове в C++, който подозирам, че ползваш. Иначе в отговор на въпроса ти за изтриването на елемент - прочети файла, после запиши в нов файл (може и същия, но като го изтриеш) всички елементи, без тези, които искаш да ги няма. При големи файлове пълното изчитане не е добра практика в общия случай заради количеството памет, което ти трябва. Отдавна не съм си играл със С++, но предполагам, че можеш да използваш някакъв seek на позицията и да си спестиш четенето на елементите до мястото на целевия елемент за триене. Тъй като вероятно всичко от този елемент нататък ще бъде изтрито при опит за писане на неговата позиция, то пак трябва да се прочете всичко от тази позиция до края на файла в буфер и после запише на мястото на елемента за изтриване. Не съм напълно сигурен дали ще стане точно така. Това последното си е просто мое разсъждение по спомени.

Поздрави
Активен
Too short signature limits.

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #2 -: 04.02.2010, 00:07:55 »

Средата която използвам е Dev C++. Намерих работещ код, с вички търсени от мен възможности, който се оказа, че работи без проблем за  Visual C, но не и за Dev. За съжаление са използвани "думи", които не са ми познати и не мога да ги адаптирам за Dev.  Програмата работи, но точно изтриването не във всички случаи се получава коректно.

Пропуснах да напиша, че се опитвам да изтрия елемент в текстов файл. Но същата възможност ме интересува и за двоичен файл.
« Последна редакция: 04.02.2010, 00:09:52 от my_form »
Активен

antoniy

  • Управител
  • *
  • Неактивен Неактивен
  • Публикации: 723
    • http://antoniy.net/
Re:Файлове в Dev С++
« Отговор #3 -: 04.02.2010, 09:31:12 »

Прочете ли какво съм написал? За сега разговора прилича повече на монолог.
Активен
Too short signature limits.

Светослав Енков

  • Неактивен Неактивен
  • Публикации: 1864
    • Shark's Home Page
Re:Файлове в Dev С++
« Отговор #4 -: 04.02.2010, 11:54:39 »

В глава 19-та (във втората част е) на учебника на Магдалина Тодорова "Програмиране на С++" има всичко, с примери, за потоците и файловете в С++, С минимални преработки си става всичко за DevC++. Предимно се променят леко описването на header-ите и параметрите на main, както и добавянето на using namespace std, ако примерите са били за VC++. Всичко останало е стандартно - езика си е С++. Конкретно в DevC++ май можеха да се закачат няколко различни компилатора, стандартно май беше mingw32. Всички примери от книгата съм ги подкарвал на DevC++.

За въпроса ти за файловете - няма готови функции за изтриване от файл. Има функция изтриване на файл. Също така, в С++, за разлика от Паскал, няма директно понятието файл от даден тип. Няма дори текстов файл. Просто някои функции на потоците добавят или четат до разделител знака за нов ред.

Какво разбираш под елемент от текстов файл? Отделна дума или отделен ред, параграф? Разделени с какво? Текстовият файл е последователен и единственият начин е да се презапише наново или целият файл или поне от мястото, където се изтрива, до края. Имаш позиция в потока, имаш функции за преместване на позицията. Имаш и йерархия на класовете, наследяващи ios. И това е.

« Последна редакция: 04.02.2010, 12:05:37 от Светослав Енков »
Активен

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #5 -: 04.02.2010, 15:00:39 »

Прочете ли какво съм написал? За сега разговора прилича повече на монолог.

Най-напред искам да благодаря за съвета. Всъщност имам следните идеи за изтриване на елемент във файл:
1. Като се запълни елемента за изтриване с празно съдържание (Магдалина Тодорова)
2. Като се запише последния елемент на мястото на елемента за изтриване и се изчисти файла до края.
3. Като се прехвърлят всички следващи елементи напред, заемайки мястото на елемента за изтриване.
4. Като се маркират елементите за изтриване и след това файлът се презапише в нов файл, като се прескочат изтритите.
Както вече написах, кода който имам работи коректно във вижуъл С, но не и в Dev. Ето го:

void Delete(fstream &iofile)
{
iofile.open("Ukazatel.txt", ios::in|ios::out);
string name;
cout<<"Enter name:";
getline(cin, name); cin.get();
string line;
int pos_write, pos_delete;
while (getline(iofile, line))
if (line.find(name)!=string::npos)
{cout<<line<<endl;
cout<<"Are you sure:(Y/N)";
char otg = cin.get(); cin.get();
if (toupper (otg)=='Y')
{iofile.seekg(-32, ios::cur);
pos_write = iofile.tellg();
iofile.seekg (-32, ios::end);
pos_delete = iofile.tellg();
getline (iofile,line);
iofile.seekp (pos_write);
iofile<<line<<endl;
int fd = _open ("Ukazatel.txt", _O_RDWR );
_chsize(fd, pos_delete);
iofile.seekg(pos_write);
}
}
iofile.clear();
iofile.close();
}
Ако някой може да ми помогне да го адаптирам за Dev C ще му бъда много благодарна.
Активен

Светослав Енков

  • Неактивен Неактивен
  • Публикации: 1864
    • Shark's Home Page
Re:Файлове в Dev С++
« Отговор #6 -: 04.02.2010, 16:02:44 »

Ох, извинявам се, не знаехме, че си колежка (не правя намек, че колежките са по-проблемни програмистки).

Не каза къде точно ти дава грешки и какви хедъри използваш?

int fd = _open ("Ukazatel.txt", _O_RDWR );
_chsize(fd, pos_delete);

Това ми дава грешка и при мен на DevC++. Откъде го изкопа този код?

P.S. Това наистина си е част от Microsoft CRTL и няма как да го има в DevC++, съжалявам!
http://msdn.microsoft.com/en-us/library/z0kc8e3z%28VS.71%29.aspx

Измисли как да замениш този код с такъв, ползващ ios обектите.
М/у другото - да отвориш вече отворен файл в друг файлов обект, за да му смениш големината,
може да го измисли само върл хакер - противоречи на всякакви идеологии и правила за мен!
« Последна редакция: 04.02.2010, 16:08:31 от Светослав Енков »
Активен

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #7 -: 04.02.2010, 16:59:18 »

Ох, извинявам се, не знаехме, че си колежка (не правя намек, че колежките са по-проблемни програмистки).
Едва ли мога да се нарека така  :roll:

Ето хедърите:

#include <iostream>
#include <fstream>
#include <string>
#include<iomanip>
#include <io.h>
#include <fcntl.h>
using namespace std;

Грешката е при изпълнение:  след избор на име за изтриване, последното се записва върху част от избраното. Тоест не се изтрива напълно. Последното се губи наистина.
Активен

Светослав Енков

  • Неактивен Неактивен
  • Публикации: 1864
    • Shark's Home Page
Re:Файлове в Dev С++
« Отговор #8 -: 04.02.2010, 17:06:23 »

А на VC++ си го изтрива коректно, така ли?

Може би, защото няма навсякъде проверки, дали файловите операции са успешни и някоя пропада?

Да, аз нямах io.h и fcntl.h, затва нямах _open() и _chsize() функциите.
« Последна редакция: 04.02.2010, 17:09:06 от Светослав Енков »
Активен

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #9 -: 04.02.2010, 17:17:23 »

Да, във Visual C работи без проблем, дори ако името се състои от 2 имена.
Активен

antoniy

  • Управител
  • *
  • Неактивен Неактивен
  • Публикации: 723
    • http://antoniy.net/
Re:Файлове в Dev С++
« Отговор #10 -: 04.02.2010, 18:36:13 »

Един съвет малко встрани от въпроса. Ако използваш езика С за тези неща ще си спестиш тези глупости покрай ios стриймове и обекти. Знанието за тях няма да ти донесе нищо особено в бъдеще, а и ако ти потрябва ще го прочетеш. В С нещата са много по-опростени, имаш функции, имаш типове и си действаш. Да си играеш с обекти без дори да пишеш ООП (да не говорим за майкрософтските извращения) ми се струва излишно и прави ученето на основните неща, свързани с файлове много по-трудно. Това е моето мнение.

Поздрави
Активен
Too short signature limits.

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #11 -: 04.02.2010, 18:53:04 »

        Вероятно в С нещата са доста подобни като на Паскал. За съжаление не избирам аз средата, в която ще се пишат програмите.
        Според мен езикът Паскал има много добри възможности за обучение в основните алгоритми, но беше отхвърлен категорично. Колко енергия се разпилява когато без подходящ учебник се иска да бъдат преподадени нови знания? (риторичен въпрос)
Активен

antoniy

  • Управител
  • *
  • Неактивен Неактивен
  • Публикации: 723
    • http://antoniy.net/
Re:Файлове в Dev С++
« Отговор #12 -: 04.02.2010, 19:04:12 »

Не става дума за среда, а за език. И между другото можеш да използваш С библиотеките за вход и изход като пишеш С++ код, който си се компилира, нормално, от С++ компилатора. Това не е проблем.
Активен
Too short signature limits.

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #13 -: 05.02.2010, 23:40:45 »

Елементите на моя файл са от тип структура с едно числово и едно символно поле с дължина 20. Запазих нулевия елемент за съхраняване на текущия брой записи във файла. Опитвам се да реализирам добавяне на елемент след последния, но сега и това не се получава (без нулевия се получаваше). Ето как изглежда моята функция за добавяне:

 void appendF()
  {
    g.open("opit1.bin",ios::in|ios::binary|ios::app);
    g.seekg(0,ios::beg);
    g.read((char*)&z,sizeof(z));
    n1=z.nomer;cout<<n1<<'\n';
    g.seekp(0,ios::end);
    cout<<"Vavedi ime:";cin>>z.ime;
    z.nomer=n1+1;
    g.write((char*)&z,sizeof(z));
    g.seekp(0,ios::beg);
    g.write((char*)&z,sizeof(z));
    g.clear();
    g.close();   
  }
Активен

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #14 -: 06.02.2010, 23:05:07 »

 Ето как изглежда работещата функция за добавяне:

 void appendF()
  {
    g.open("buff.bin",ios::out|ios::in|ios::binary);
    g.seekg(0,ios::beg);
    g.read((char*)&z,sizeof(z));
    n1=z.nomer;
    cout<<n1<<'\n';
    g.clear();
    g.seekp(0,ios::end);
    cout<<"Vavedi ime:";cin>>z.ime;g.clear();
    z.nomer=n1+1;
    g.write((char*)&z,sizeof(z));
    g.flush();
    g.seekp(0,ios::beg);
    g.write((char*)&z,sizeof(z));
    g.flush();
    g.close();  
  }

Остана да измисля изтриването.

P.S. Явно не мога да редактирам стари мнения.
« Последна редакция: 06.02.2010, 23:08:59 от my_form »
Активен

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #15 -: 09.02.2010, 21:45:40 »


В средата Dev C++,  EOF  е макрос. Как мога да го добавя на избрана позиция във файла?
Активен

antoniy

  • Управител
  • *
  • Неактивен Неактивен
  • Публикации: 723
    • http://antoniy.net/
Re:Файлове в Dev С++
« Отговор #16 -: 10.02.2010, 09:26:09 »

EOF == End Of File

Каква позиция, какви 5 лв?
Активен
Too short signature limits.

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #17 -: 10.02.2010, 16:08:28 »

              Опитвам се да следвам идеята: нулевият запис съхранява информация за броя записи във файла (това е ясно и от функцията за добавяне, според мен).
              При изтриване вземам последния елемент във файла и го записвам на мястото на посочения елемент за изтриване. Сега трябва да "отрежа" последния елемент от файла, за да не е достъпен при следващи обработки. Мислех си, че това мога да направя като сложа знак за край на файла на избрана от мен позиция. Как става това? Ако EOF е макрос, как се използва той?
              В други версии на езика С има режим ios::trunc има функции  truncate, ftruncate. Как да постигна същия ефект в Dev C за двоични, а не за текстови файлове?
Активен

Светослав Енков

  • Неактивен Неактивен
  • Публикации: 1864
    • Shark's Home Page
Re:Файлове в Dev С++
« Отговор #18 -: 10.02.2010, 16:23:03 »

EOF е едновременно и знак за край на файла (ctrl-Z), но само при текстови файлове; така и функция, показваща true, ако в момента файловият указател е достигнал краят на файла (предимно за бинарни файлове, но сигурно работи и с текстови, т.к. реално няма разлика в С/С++ м/у тях).

Не може да няма Truncate (като дума, термин) метод (функция) в класа ios и наследниците му в DevC++ - все пак това е стандартна библиотека. Точно затова мразя DevC++, че не е окомплектован с нормална, добре попълнена система за помощ за класовете с примери и референции, каквото е MSDN (или помощната система на Borland C++).
Активен

my_form

  • Неактивен Неактивен
  • Публикации: 45
Re:Файлове в Dev С++
« Отговор #19 -: 11.02.2010, 20:40:50 »

        При изтриване няма начин да не се използва chsize(fd,size); - за смяна размера на файла, която се намира във fcntl.h, тоест това беше което търсех за изрязване от файла. Това са следните два реда, от първия вариант на функцията за изтриване, които се изпълняват и без подчертаващите тирета:

int fd = _open ("Ukazatel.txt", _O_RDWR );  //този параметър _O_RDWR може да се замести с 2
_chsize(fd, pos_delete);


След добре свършена работа  се полага поне малко музика:  :#7:
http://www.youtube.com/watch?v=2S_YrqdA_40&feature=related

    Поздрав към всички, които ми помогнаха!
« Последна редакция: 11.02.2010, 20:43:11 от my_form »
Активен