Четене и запис на файлове

     О. Езика за програмиране с++ дава възможност за дълготрайно съхранение на информацията във вид на файлове, което означава, че след като изклучим компютъра информацията ни няма да е изчезнала.
Съществува специален тип за работа с указатели - файлов указател.
      Декларация на файлов указател :
            FILE *fp;
fp - име на файловия указател;
След като е деклариран файловия указател с него можем да отваряме, четем, записваме текстови данни, чрез функцията fopen();
        FILE *fp;
        fp=fopen("Име на файл","режим за достъп");

Име на файл - създавате си име и задавате местоположението на файла;
Режим за достъп - латински букти, който съответстват за определен режим за достъп;
    fp=fopen("c:/test/data.txt","w");
Името на файла е data.txt и местоположението му. Обърнете внимание, как се достига до местоположението на файла и папката test трябва предварително да бъде създадена .
След приключване на работа с файла той трябва да бъде затворен с функцията fclose(fp) където :
    fp - името на файловия указател, който искаме да затворим;
     Можем да работим с няколко файлови указатела. Режимите на достъп са:
w - създаване на текстов файл за запис,
     ако няма такъв създава нов, ако вече съществува
     такъв файл, отваря го но преди това изчиства съдържанието му;
r      - отваря текстов файл за четене;
a     - добавяне към края на съществуващ файл, ако не съществува го създава;
w+    - отваряне на текстов файл за запис или четене;
r+    - отваряне на текстов файл за четене или запис;
a+    - добавя или създава текстов файл за четене или запис;
( wb,wb+,w+b, rb, rb+,r+b, ab, ab+, a+b ) - извършват същите режими,
но при работа с двойчни файлове.
       Ако функцията не може да създаде или прочете файл, връща
нулев файлов указател.В програмите се проверява указателя по този начин:
if (f!=NULL) означава,че файла е отворен правилно
{ }
else
{
cout<< "Unable to created\n"; възникване на грешка
}
      Макроса EOF или feof (f се пише за работа с файлове)
се използва проверка при достигане край на файл :
if (!feof(fp)) { действе }- ако не е достигнат края на файла,
извършвай някакви действия.
Обикновенно EOF e отрицателна стойност (-1).
Ето няколко примера:
   Пример 1 : Създаване на файл myfile.txt в папка test на локален диск c .
Записва се съдържанието на низ str символ по символ.
Папката test трябва предварително да сте я създали!
За по-любознателните в раздел "задачи" пример №5 съдържа програма на с++, която създава директория под DOS.

#include <iostream> //for Code Blocks
#include <stdio.h>
using namespace std;
int main()
{
FILE * f;
char str[50]="Simple sentence... \n";
int i;
f=fopen("c:/test/myfile.txt","a");
// f=fopen("test/myfile.txt","a");             for Eclipse/Linux
if (f!=NULL)
{
cout<< "File is created\n";
for (i=0;str[i];i++)
{fputc(str[i],f);
}
fclose(f);
return 0;
}
else
{
cout<< "Unable to created\n";
return 1;
}
}
Прочитането на файла myfile.txt за сега може да се осъществи чрез Notepad .

   Пример 2 : Прочитаме съдържанието (от пример 1) на файла myfile.txt от папка test на локален диск c .
Четем съдържанието на низ str символ по символ.

#include <iostream> //for Code Blocks
#include <stdio.h>
#include<string.h>
using namespace std;
int main ()
{
FILE * f;
char str;
f=fopen("c:/test/myfile.txt","r");
// f=fopen("test/myfile.txt","r");             // for Eclipse/Linux
if (f!=NULL)
{
cout<< "File is open for reading ...\n";
{
do
{
str=fgetc(f);
cout<< str;
}
while (!feof(f));
}
fclose(f);
return 0;
}
else
{
cout<< "Unable to reading\n";
return 1;
}
}
   Пример 3 : Създаване на файл myfile1.txt в папка test на локален диск c .
Записвaме колкото си искаме редове. Записването приключва след като
натиснете клавиша Enter на празен ред.
   Папката test , трябва да се създаде предварително.

#include <iostream> //for Code Blocks/ Windows
#include<stdio.h>
#include<string.h>
using namespace std;
int main ()
{
FILE * fp;
char str[80];
fp=fopen("c:/test/myfile1.txt","w");
if (fp!=NULL)
{
{
do
{
gets(str);
strcat(str,"\n");
if (*str!='\n')
fputs (str,fp);
}
while (*str!='\n');
cout<< "File is created\n";
}
fclose(fp);
return 0;
}
else
{
cout<< "Unable to created\n";
return 1;
}
}

Прочитането на файла myfile1.txt за сега може да се осъществи чрез Notepad

Папката test ,надявам се вече сте я създали.
      Обяснение на програмата :
Функцията gets(str) - записва знаците от реда, който въвеждаме.
Израза strcat(str,"\n"); добавяме знак за нов ред, защото в противен случай
ще ни залепи всички редове във файла.
Израза if (*str!='\n') - проверява дали реда е празен, ако е празен записва файла
чрез реда fputs (str,fp);



   Пример 3-1 :
Същият пример 3, но написан за Eclipse на Linux?!?


#include <iostream> //for Eclipse/ Linux
#include<stdio.h>
#include<string.h>
using namespace std;
int main ()
{
FILE * fp;
char str[80];
fp=fopen("test/myfile1.txt","w");
if (fp!=NULL)
{
{
do
{
fgets(str, 80, stdin);
if (*str!='\n')
fputs (str,fp);
}
while (*str!='\n');
cout<< "File is created\n";
}
fclose(fp);
return 0;
}
else
{
cout<< "Unable to created\n";
return 1;
}
}

      Обяснение на програмата :
Функцията fgets(str, 80, stdin); - записва знаците от реда, който въвеждаме.
Израза strcat(str,"\n"); добавяме знак за нов ред, защото в противен случай
ще ни залепи всички редове във файла.
Израза if (*str!='\n') - проверява дали реда е празен, ако е празен записва файла
чрез реда fputs (str,fp);



   Пример 4 : Четене на файл myfile1.txt в папка test на локален диск c .
Прочитаме целия файл ред по ред.

#include <iostream> //for Code Blocks
#include<stdio.h>
#include<string.h>
using namespace std;
main ()
{
FILE * fp;
char str[80];
int i;
fp=fopen("c:/test/myfile1.txt","r");
if (fp!=NULL)
{
cout<< "File is open for reading ...\n";
{
do
{
fgets(str,79,fp);
if (!feof(fp))
cout<< str;
}
while (!feof(fp));
}
fclose(fp);
return 0;
}
else
{
cout<< "Unable to created\n";
return 1;
}
}
     

Произволен достъп до файл
     Чрез функцията fseek() можете да имате достъп до произволна позиция от файл.
        Нейният прототип е:
int fseek(FILE *fp, long отместване, int начална стойност)

      long отместване - отместването от текучата позиция;
      int начална стойност - задава началната позиция от къде да започне търсенето;
може да бъде зададена от следните макроси:
         SEEK_SET - търсенето започва от началото на файл;
         SEEK_CUR - търсенето започва от текущата позиция на файловия указател;
         SEEK_END - търсенето започва от края на файл;
 Функцията fseek() връща нулев указател при успешно завършване на търсенето и стойност различна от 0 при грешка.

Друга функция е ftell () , нейният прототип е:
long int ftell ( FILE * fp );
Tя връща текущата позиция на файловия указател fp, при грешка връща -1.
    

   Пример 5 : Създаване на файл example.txt.
Записвaме един ред:"This is an apple.". След това от 8 позиция записваме "two" и в края на реда от 17 позиция добавяме "s."

#include<stdio.h>
using namespace std;
int main ()
{
FILE * fp;
fp = fopen ( "example.txt" , "wb" );
fputs ( "This is an  apple." , fp );
fseek ( fp , 8 , SEEK_SET );
fputs ( "two " , fp );
fseek ( fp ,17 , SEEK_SET);
fputs ( "s." , fp );
fclose ( fp );
return 0;
}

Благодаря за вниманието Ви !