Работа с файлове

При работа с файлове в C++ трябва да се има предвид, че файловете могат да се отворят като текстови или двоични. Съдържанието на текстовите файлове може да се види и с Notepad, докато на двоичните ще виждате непознати символи.

Независимо, дали сте записали дадено число в текстов файл като символ или като число, то ще се интерпретира като символ. Например, ако запишете в текстов файл цялото числото 123, което заема 2 байта, в последствие, за да го прочетете, всъщност ще се наложи да прочетете 3 байта, защото веднъж записано в текстовия файл, то вече се възприема като символен низ, в който всеки символ заема един байт. Следователно преди да започнете реализацията на програмата, трябва да помислите какъв файл ви е нужен. Ако ще се налага да четете от него различни по тип данни, задължително трябва да създадете двоичен файл.

 

Създаване, отваряне и затваряне на файл

За да можете да работите с даден файл, първо трябва да дефинирате променлива, която да свържете с него. Това става със следния код:

FILE *fp;   //fp е името на файловата променлива

След това физическия файл трябва да се отвори в някой от следните режими:

Четене (read) – в този режим може само да се чете от файла, ако файла не съществува се получава съобщение за грешка

Запис (write) – в този режим от файла не може да се чете, а само да се записва като при всяко следващо изпълнение съдържанието на файла се изтрива и на негово място се записват новите данни. Ако файла не съществува, той бива създаден.

Добавяне (append) – в този режим от файла не може да се чете, а само да се записва като новите данни се добавят в края на файла. Ако файла не съществува, той бива създаден.

Свързването на логическата променлива с физическия файл става така:

fp = fopen(“име_на_файл”,режим”);

име_на_файл е името на физическия файл, които искате да отворите, а за режим можете да изберете една от следните възможности:

r – отваряне за четене на текстов файл

w – създаване / отваряне за запис на текстов файл

a – създаване / отваряне за добавяне на текстов файл

r+ – отваряне за четене и запис на текстов файл

w+ – създаване / отваряне за четене и запис на текстов файл

a+ – създаване / отваряне за четене и добавяне на текстов файл

rb – отваряне за четене на двоичен файл

wb – създаване / отваряне за запис на двоичен файл

ab – създаване / отваряне за добавяне на двоичен файл

rb+ – отваряне за четене и запис на двоичен файл

wb+ – създаване / отваряне за четене и запис на двоичен файл

ab+ – създаване / отваряне за четене и добавяне на двоичен файл

След като приключите работата с даден файл по правило трябва да го затворите. Това става с функцията

fclose(fp);

Действието може да се пропуска в края на програмата, защото тогава автоматично се затварят всички използвани файлове. Затварянето на файл е задължително, ако след това ще го отваряте в друг режим – например записвали сте нещо, след което го затваряте и го отваряте за четене.

 

Друга функция, която може да се наложи да използвате е:

rewind(fp);  //връща в началото на файла

 

Функции за работа с текстови файлове:

c=fputc(fp); //чете един байт (символ) от файла fp и го присвоява на c

fgetc(c. fp); //записва един символ (c) във файла fp

fputs(str, fp); //записва цял низ (от str) във файла fp

fgets(str, номер, fp); //чете низ до знака с номер номер-1

fprintf(fp, „контролен низ”, списък_стойности); //форматиран изход във файл

fscanf(fp, „контролен низ”, списък_променливи); //форматиран вход от файл

При последните две се работи както с функциите за форматиран вход / изход printf и scanf, например:

fprintf(fp, „%f”, а); //записва стойността на променливата а (тип float) във файла fp

fscanf(fp, „%d”, &b); //чете цяло число (2 байта) от файла fp и го записва в b

 

Функции за работа с двоични файлове:

fread(buffer, размер, n, fp); //прочита n броя обекти с размер в байтове, равен на размер, и ги дава като стойност на buffer

fwrite(buffer, размер, n, fp); //записва n броя обекти с размер в байтове, равен на размер, които взема от buffer

Обикновено n=1, понеже в повечето случаи се записва или чете по един обект.

Размера може да се зададе по няколко начина:

  • ако знаете размера в байтове на конкретната данна, която ще четете го записвате с число, например, ако четем цело число (тип int), пишем 2, за дробно (float) – 4 и т.н.;
  • ако знаем типа, но не сме сигурни колко байта заема, записваме sizeof(тип), например sizeof(int), sizeof(float) и т.н.;
  • като го зададем според променливата, с която ще четем стойност. Това става като запишем sizeof(име_на_променливата), например sizeof(a). По този начин може да четем всякакви типове данни, включително по-сложни като масив и структура, затова този метод е за предпочитане.

 

Пример:

int a;

fread(&а, sizeof(a), 1, fp); //чете (и записва в а) едно цяло число (два байта) от файла fp

fwrite(&а, sizeof(a), 1, fp); //записва стойността на а (цяло число) във файла fp

 

 

Примери:

Прочитане на цял текстов файл:


do {
ch=fgetc(fp);
cout<<ch;
} while (ch!=EOF);

 

Запис в текстов файл с fprintf

Първо се записва hello :), след което се четат две цели числа и във файла се записва един ред във вида: първото + второто = сбора им, например 2 + 3 = 5


fprintf(fp, “hello 🙂 \n”);
cin>>a;
cin>>b;
fprintf(fp, “%d + %d = %d \n”, a, b, a+b);

 

Примерни задачи:

Задача_1: Записва символът „а” в текстов файл, след което връща в началото на файла и прочита един символ, който извежда на екрана. С този пример се демонстрират функциите fputc, fgetc и rewind. Файла се създава в режим за четене и запис.

Задача_2: Записва произволен брой цели числа, избран от потребителя във файл, след което прочита от файла толкова числа, колкото желае потребителя, освен ако те не надминават въведения със файла брой. За целта файла се отваря два пъти – веднъж в режим на двоичен запис, и втори път за двоично четене. Самото записване / четене е организирано в цикъл. Използваните променливи са i за циклите, x за числата, n_write и n_read за определяне брой числа за запис и четене от файла.

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

Практически задачи / dat файла за вариант 1 и 2