How to set up smartphones and PCs. Informational portal

Opening a file. Data input from file and output to file

Working with text files in C++.

There are two main types of files: text and binary. Files allow the user to read large amounts of data directly from disk without typing it in from the keyboard.

    Text are called files consisting of any characters. They are organized into lines, each of which ends with an end-of-line character. The end of the file itself is indicated by the symbol "end of file". When writing information to a text file, which can be viewed using any text editor, all data is converted to a character type and stored in character form.

    IN binary In files, information is read and written in the form of blocks of a certain size, in which data of any kind and structure can be stored.

To work with files, special data types, called streams. Flow ifstream is used to work with files in read mode, and outstream in recording mode. A stream is used to work with files in both write and read mode. fstream.

In C++ programs, when working with text files, it is necessary to include the iostream and fstream libraries.

In order to write down data into a text file, you must:

    describe a variable of type ofstream.

    output information to a file.

    be sure to close the file.

For readings data from a text file, you must:

    describe a variable of type ifstream.

    open a file using the open function.

    close the file.

Recording information to a text file

    As mentioned earlier, in order to start working with a text file, you need to declare a variable of the ofstream type. For example, like this:

    A variable F will be created to write information to the file.

    The next step is to open the file for writing. In general, the stream opening operator will look like:

F. open("file", mode);

Here F is a variable declared as ofstream,

file - the full name of the file on the disk,

mode - mode of operation with the opened file.

Please note that when specifying the full file name, you must put a double slash. For example, the full name of the noobs.txt file located in the game folder on the D: drive will need to be written like this:

D:\\game\\noobs.txt.

The file can be opened in one of the following modes:

ios::in - open file in read data mode, this mode is the default mode for ifstream streams;

ios::out - open file in data writing mode (in this case, information about the existing file is destroyed), this mode is the default mode for streams ofstream;

ios::app - open a file in the mode of writing data to the end of the file;

ios::ate - move to the end of an already open file;

ios::trunc - clear the file, the same happens in ios::out mode;

ios::nocreate - do not open file if it does not exist;

ios::noreplace - Don't open an existing file.

The mode parameter may be absent, in which case the file is opened in the default mode for this stream.

After a successful file opening (in any mode), the F variable will store true, otherwise false. This will check the correctness of the file open operation.

You can open a file (let's take D:\\game\\noobs.txt as an example) in write mode using one of the following methods:

// first way

offstream F;

F.open("D:\\game\\noobs.txt", ios::out);

//second way, ios::out mode is the default mode

// for flowoutstream

offstream F;

//the third way combines the description of the variable and the stream type

//and open file in one statement

ofstream F("D:\\game\\noobs.txt", ios::out);

After opening a file in write mode, an empty file will be created into which information can be written.

If you want to open an existing file in pre-write mode, use ios::app as the mode.

After opening a file in write mode, you can write to it in the same way as on the screen, only instead of the standard output devicecoutyou must specify the name of the open file.

For example, to write variable a to stream F, the output statement would be:

To sequentially print the variables b, c, d to the stream G, the output statement becomes:

G<

The stream is closed using the operator:

EXAMPLE:

Create a text file D:\\game\\noobs.txt and write n real numbers into it.

#include "stdafx.h"

#include

#include

#include

using namespace std;

int main()

setlocale(LC_ALL, "RUS");

int i, n;

double a;

//describes a stream for writing data to a file

outstream f;

//open file in write mode,

//modeios:: outinstalled by default

f.open("D:\\game\\noobs.txt", ios::out);

//enter the number of real numbers

cout<<" n="; cin>> n;

//loop for entering real numbers

//and writing them to a file

for (i=0; i

cout<<"a=";

//input number

cin>>a;

f<

//closing the stream

f.close();

system("pause");

return 0;

_______________________________________________________________

In order to read information from a text file, it is necessary to declare a variable of type ifstream. After that, you need to open the file for reading using the operator open. If the variable is called F, then the first two statements will be as follows:

F.open("D:\\game\\noobs.txt", ios::in);

After opening a file in read mode, you can read information from it in the same way as from the keyboard, only instead ofcinspecify the name of the stream from which the data will be read.

For example, to read from stream F into variable a, the input statement would look like this:

Two numbers in a text editor are considered separated if there is at least one of the characters between them: space, tab, end-of-line character. It is good if the programmer knows in advance how many and what values ​​to store in a text file. However, often the type of values ​​stored in the file is simply known, and their number can vary. To solve this problem, you need to read the values ​​from the file one at a time, and before each read, check whether the end of the file has been reached. There is a function for this F. eof().

Here F is the name of the stream, the function returns a boolean value: true or false, depending on whether the end of the file has been reached. Therefore, a loop to read the contents of the entire file can be written like this:

//organize for reading values ​​from a file, execution

//the loop will break when we reach the end of the file,

//in this case F.eof() will return true

while (!F.eof())

EXAMPLE:

Real numbers are stored in the text file D:\\game\\noobs.txt, display them on the screen and calculate their number.

#include "stdafx.h"

#include

#include

#include

#include

using namespace std;

int main()

setlocale(LC_ALL, "RUS");

intn=0;

float a;

fstream F;

//open file in read mode

F.open("D:\\game\\noobs.txt");

//if the file was opened correctly, then

//loop for reading values ​​from a file; loop execution will be interrupted,

//when we reach the end of the file, in which case F.eof() will return true.

while (!F.eof())

//reading the next value from stream F into variable a

F>>a;

//output the value of the variable a on the screen

cout<

//increase the number of read numbers

//closing the stream

f.close();

//entering the number of read numbers on the screen

cout<<"n="<

//if the file was opened incorrectly, then the output

//messages about the absence of such a file

else cout<<" Файл не существует"<

system("pause");

return 0;

C++. Processing binary files

When writing information to a binary file, characters and numbers are written as a sequence of bytes.

In order to write down data into a binary file, you need:

    declare a file variable of type FAIL * using the FILE *filename; statement. Here filename is the name of the variable where the pointer to the file will be stored.

    write information to a file using the fwrite function

In order to think z data from a binary file, you must:

    describe a variable of type FILE *

    open file with fopen function

    close file with fclose function

Basic functions required to work with binary files.

For discoveries file, the fopen function is intended.

FILE *fopen(const *filename, const char *mode)

Here filename is a string that stores the full name of the file being opened, mode is a string that defines the mode of working with the file; the following values ​​are possible:

"rb" - open binary file in read mode;

"wb" - create a binary file for writing; if it exists, its contents are cleared;

"ab" - create or open a binary file for appending to the end of the file;

"rb+" - open an existing binary file in read-write mode;

"wb+" - open a binary file in read-write mode, the existing file is cleared;

"ab+" - A binary file is opened or created to correct existing information and add new information to the end of the file.

The function returns the NULL value in the file variable f if the file was not successfully opened. After the file is opened, its 0th byte is available, the file pointer is 0, the value of which is shifted by the read (written) number of bytes as it is read or written. The current value of the file pointer is the byte number from which the read or write operation will occur.

For closing file, the fclose function is intended

int fclose(FILE *filename);

Returns 0 if the file was successfully closed, NULL otherwise.

The remove function is for removal files.

int remove(const char *filename);

This function removes a file named filenema from disk. The file to be deleted must be closed. The function returns a non-zero value if the file could not be deleted.

For renaming files, the rename function is intended:

int rename(const char *oldfilename, const char *newfilename);

The first parameter is the old file name, the second is the new one. Returns 0 on successful completion of the program.

Reading from a binary file is done using the fread function:

fread(void *ptr, size, n, FILE *filename);

The fread function reads n elements of size size from the file filename into the ptr array. The function returns the number of elements read. After reading from a file, its pointer is shifted by n*size bytes.

Recording to a binary file is done using the fwrite function:

fwrite(const void *ptr, size, n, FILE *filename);

The fwrite function writes n elements of size size to the file filename from the ptr array. The function returns the number of written elements. After the information is written to the file, the pointer is shifted by n*size bytes.

For end-of-file control there is a feof function:

int feof(FILE *filename);

It returns a non-zero value if the end of the file is reached.

EXAMPLE:

Create a binary file D:\\game\\noobs.dat and write an integer n and n real numbers into it.

#include "stdafx.h"

#include

using namespace std;

int main()

setlocale(LC_ALL, "RUS");

int n, i;

double a;

// create binary file in write mode

f=fopen("D:\\game\\noobs.dat", "wb");

// input numbersn

cout<<"n="; cin>>n;

fwrite(&n, sizeof(int), 1, f);

//loop to enter n real numbers

for (i=0; i

//input the next real number

cout<<"a=";

cin>>a;

//write real number to binary file

fwrite(&a, sizeof(double), 1, f);

// close file

fclose(f);

system("pause");

return 0;

EXAMPLE:

Display the contents of the binary file D:\\game\\noobs.dat created in the previous task

#include "stdafx.h"

#include

using namespace std;

int main()

setlocale(LC_ALL, "RUS");

int n, i;

double *a;

FILE *f; //describe file variable

//open existing binary file in read mode

//read one integer from the file into the variable n

//output n to the screen

cout<<"n="<

//allocate memory for an array of n numbers

a=new double[n];

//reading n real numbers from file into array a

//output the array to the screen

for (i=0; i

cout<

cout<

// close file

fclose(f);

system("pause");

return 0;

Binary- sequential data structure, after opening the file, the first byte stored in it is available. You can sequentially write or read data from a file. Suppose you need to count the fifteenth number, and then the first. With serial access, this can be done in the following way:

int n, i;

double a;

FILE *f;

f=fopen("D:\\game\\noobs.dat", "rb");

for (i=0; i<15; i++)

fclose(f);

f=fopen("D:\\game\\noobs.dat", "rb");

fread(&a, sizeof(double), 1, f);

fclose(f);

As you can see, reading numbers from a file and then reopening the file is not the most convenient way. It is much more convenient to use the fseek function to move the file pointer to a given byte.

int fseek(FILE *filename, long int offset, int origin);

The function sets the pointer to the current position of the file F in accordance with the value of origin and offset offset. The offset parameter is equal to the number of bytes by which the file pointer will be shifted relative to the origin specified by the origin parameter. The value for the origin parameter must be one of the following values ​​for offset, defined in the stdio.h header:

SEEK_SET - from the beginning of the file;

SEEK_CUR - from the current position;

SEEK_END - from the end of the file.

The function returns zero if the operation is successful, non-zero if the offset fails.

The fseek function actually implements direct access to any value in the file. You only need to know the location (byte number) of the value in the file. Consider the use of direct access in binary files using the example of solving the following problem.

EXAMPLE

In the binary file D:\\game\\noobs.dat created earlier, swap the largest and smallest of the real numbers.

The algorithm for solving the problem consists of the following steps:

    reading reals from a file into an array a.

    search in array a for maximum (max) and minimum (min) values ​​and their numbers (imax, imin).

    moving the file pointer to the maximum value and writing min.

    moving the file pointer to the minimum value and writing max.

Below is the text of the program for solving the problem with comments.

#include "stdafx.h"

#include

using namespace std;

int main()

setlocale(LC_ALL, "RUS");

int n, i, imax, imin;

double *a, max, min;

FILE *f;

//open file in read/write mode

f=fopen("D:\\game\\noobs.dat", "rb+");

//read from file to variable n number

//real numbers in the file

fread(&n, sizeof(int), 1, f);

cout<<"n="<

//allocate memory to store real numbers,

//which will be stored in array a

a=new double[n];

//read from the file into an array and real numbers

fread(a, sizeof(double), n, f);

//search for the maximum and minimum elements

//in array a and their indices

for (imax=imin=0, max=min=a, i=1; i

if (a[i]>max)

max=a[i];

if (a[i]

min=a[i];

// moving pointer to maximum element

fseek(f, sizeof(int)+imax*sizeof(double), SEEK_SET);

//recording min instead of the maximum element of the file

fwrite(&min, sizeof(double), 1, f);

// moving pointer to minimum element

fseek(f, sizeof(int)+imin*sizeof(double), SEEK_SET);

//record max instead of minimum file element

fwrite(&max, sizeof(double), 1, f);

//closing the file

fclose(f);

// free memory

delete[ ]a;

system("pause");

Text files

Let's consider working with a text file in C using an example. Create a text file on drive C called TextFile.txt. Type the following lines in this file:

String_1 123 String_11, 456
String_2
String_3

Save the file.

And this is the code for the C program that opens our file and reads lines from it:

/* *Author: @author Subbotin B.P..h> #include #define LEN 50 int main(void) ( puts("Text file operations"); char cArray; FILE *pTextFile = fopen("C:\\TextFile.txt", "r"); if(pTextFile == NULL) ( puts("Problems"); return EXIT_FAILURE; ) while(fgets(cArray, LEN, pTextFile) != NULL) ( printf("%s", cArray); ) fclose(pTextFile); return EXIT_SUCCESS; )

To open a text file in C, use the fopen function:

FILE *pTextFile = fopen("C:\\TextFile.txt", "r");

The first argument to the fopen function points to a file, and the second one says that the file is open for reading from it.

We read the lines using the fgets function:

fgets(cArray, LEN, pTextFile);

The first argument of the fgets function points to an array of characters in which the received strings will be stored, the second argument is the maximum number of characters to read, the third is our file.

After you finish working with the file, you need to close it:

fclose(pTextFile);

We get:

Russian letters in the lines also pass.

By the way, I made this program in Eclipse. You can see how to work with C/C++ in Eclipse.

So, we opened and read data from a text file.

Now let's learn how to programmatically create a text file and write data to it.

/* Author: @author Subbotin B.P..h> #include int main(void) ( FILE *pTextFile = fopen("C:\\TextFileW.txt", "w"); char *cString = "This is a string"; char cNewLine = "\n"; int nVal = 123 ; if(pTextFile == NULL) ( puts("Problems"); return EXIT_FAILURE; ) fprintf(pTextFile, "%s%c", cString, cNewLine); fprintf(pTextFile, "%d", nVal); return EXIT_SUCCESS ; )

Create a text file to write data to it:

FILE *pTextFile = fopen("C:\\TextFileW.txt", "w");

if the file already exists, it will be opened and all data will be deleted from it.

The C-string cString and the number nVal are written by the program to a text file. cNewLine is just a line break.

We write data to a text file using the fprintf function:

fprintf(pTextFile, "%s%c", cString, cNewLine);

the first argument here is our file, the second is the format string, the third or more is the number of arguments needed for this format.

For ease of handling, information in storage devices is stored in the form of files.

File is a named area of ​​external memory allocated for storing an array of data. The data contained in the files are of the most diverse nature: programs in algorithmic or machine language; initial data for the operation of programs or results of program execution; arbitrary texts; graphics, etc.

Directory (folder, directory) - a named collection of bytes on a storage medium containing the names of subdirectories and files, used in the file system to simplify the organization of files.

file system is a functional part of the operating system that provides operations on files. Examples of file systems are FAT (FAT - File Allocation Table, file allocation table), NTFS, UDF (used on CDs).

There are three major versions of FAT: FAT12, FAT16, and FAT32. They differ in the bitness of records in the disk structure, i.e. the number of bits allocated to store the cluster number. FAT12 is mainly used for floppy disks (up to 4 KB), FAT16 for small disks, FAT32 for high-capacity FLASH drives (up to 32 GB).

Consider the structure of the file system using FAT32 as an example.

FAT32 file structure

External memory devices in the FAT32 system are not byte, but block addressing. Information is written to an external memory device in blocks or sectors.

Sector - the minimum addressable unit of information storage on external storage devices. Typically, the sector size is fixed at 512 bytes. To increase the address space of external memory devices, sectors are combined into groups called clusters.

A cluster is an association of several sectors, which can be considered as an independent unit with certain properties. The main property of a cluster is its size, measured in the number of sectors or the number of bytes.

The FAT32 file system has the following structure.

Clusters used for writing files are numbered starting from 2. As a rule, cluster #2 is used by the root directory, and starting from cluster #3, the data array is stored. Sectors used to store information above the root directory are not clustered.
The minimum file size on disk is 1 cluster.

The boot sector begins with the following information:

  • EB 58 90 - unconditional branch and signature;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 - the number of bytes in the sector (usually 512);
  • 1 byte - the number of sectors in the cluster;
  • 2 bytes - the number of spare sectors.

In addition, the boot sector contains the following important information:

  • 0x10 (1 byte) – number of FAT tables (usually 2);
  • 0x20 (4 bytes) - the number of sectors on the disk;
  • 0x2C (4 bytes) – root directory cluster number;
  • 0x47 (11 bytes) – volume label;
  • 0x1FE (2 bytes) - Boot sector signature (55 AA).

The file system information sector contains:

  • 0x00 (4 bytes) – signature (52 52 61 41 );
  • 0x1E4 (4 bytes) – signature (72 72 41 61 );
  • 0x1E8 (4 bytes) – number of free clusters, -1 if not known;
  • 0x1EC (4 bytes) – number of the last recorded cluster;
  • 0x1FE (2 bytes) - signature (55 AA).

The FAT table contains information about the state of each cluster on the disk. The lower 2 bytes of the FAT table store F8 FF FF 0F FF FF FF FF (corresponding to the state of clusters 0 and 1, physically absent). Further, the state of each cluster contains the number of the cluster in which the current file continues or the following information:

  • 00 00 00 00 – the cluster is free;
  • FF FF FF 0F is the end of the current file.
  • 8 bytes - file name;
  • 3 bytes - file extension;

The root directory contains a set of 32-bit information records for each file containing the following information:

When working with long file names (including Russian names), the file name is encoded in the UTF-16 encoding system. In this case, 2 bytes are allocated for encoding each character. In this case, the file name is written in the form of the following structure:

  • 1 byte sequence;
  • 10 bytes contain the lower 5 characters of the filename;
  • 1 byte attribute;
  • 1 byte reserved;
  • 1 byte - DOS name checksum;
  • 12 bytes contain the lower 3 characters of the filename;
  • 2 bytes – number of the first cluster;
  • the remaining characters of the long name.

Working with Files in C

To the programmer, an open file is represented as a sequence of data being read or written. When a file is opened, it is associated with I/O flow. Output information is written to the stream, input information is read from the stream.

When a stream is opened for I/O, it is associated with the standard structure of type FILE , which is defined in stdio.h . The FILE structure contains the necessary information about the file.

Opening a file is done using the fopen() function, which returns a pointer to a structure of type FILE , which can be used for subsequent operations on the file.

FILE *fopen(name, type);


name is the name of the file to be opened (including the path),
type is a pointer to a string of characters that define how the file is accessed:
  • "r" - open file for reading (file must exist);
  • "w" - open an empty file for writing; if the file exists, its contents are lost;
  • "a" - open file for writing to the end (for appending); the file is created if it does not exist;
  • "r+" - open file for reading and writing (file must exist);
  • "w+" - open an empty file for reading and writing; if the file exists, its contents are lost;
  • "a+" - open the file for reading and appending, if the file does not exist, it is created.

The return value is a pointer to the open stream. If an error is found, NULL is returned.

The fclose() function closes the stream or streams associated with files opened with fopen(). The stream to be closed is determined by the argument of the fclose() function.

Return value: value 0 if the stream was closed successfully; the EOF constant if an error occurred.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include
int main() (
FILE *fp;
char name = "my.txt" ;
if ((fp = fopen(name, "r" )) == NULL )
{
printf( "Could not open file");
getchar();
return 0;
}
// open file succeeded
... // required actions on data
fclose(fp);
getchar();
return 0;
}

Reading a character from a file:

char fgetc(stream);


The function argument is a pointer to a stream of type FILE . The function returns the code of the read character. If the end of file is reached or an error occurs, the EOF constant is returned.

Writing a character to a file:

fputc(character, stream);

The function's arguments are a character and a pointer to a stream of type FILE . The function returns the code of the read character.

The fscanf() and fprintf() functions are similar to the scanf() and printf() functions, but operate on data files and have a file pointer as their first argument.

fscanf(stream, "InputFormat" , args);

To the programmer, an open file is represented as a sequence of data being read or written. When a file is opened, it is associated with I/O flow . Output information is written to the stream, input information is read from the stream.

When a stream is opened for I/O, it is associated with the standard structure of type FILE, which is defined in stdio.h. The FILE structure contains the necessary information about the file.

Opening a file is done using the fopen() function, which returns a pointer to a structure of type FILE, which can be used for subsequent operations with the file.

FILE *fopen(name, type);

name is the name of the file to be opened (including the path),
type - a pointer to a string of characters that define how the file is accessed:

· "r" - open the file for reading (the file must exist);

· "w" - open an empty file for writing; if the file exists, its contents are lost;

· "a" - open file for writing to the end (for appending); the file is created if it does not exist;

· "r+" - open the file for reading and writing (the file must exist);

· "w+" - open an empty file for reading and writing; if the file exists, its contents are lost;

· "a+" - open the file for reading and appending, if the file does not exist, it is created.

The return value is a pointer to the open stream. If an error is found, NULL is returned.

The fclose() function closes the stream or streams associated with files opened with fopen(). The stream to be closed is determined by the argument of the fclose() function.

Return value: value 0 if the stream was closed successfully; the EOF constant if an error occurred.

#include
int main()

char name="my.txt";

if(fp = fopen(name, "r")!=NULL)

// was it possible to open the file?
... // required actions on the data

else printf("Could not open file");

Reading a character from a file:

char fgetc(stream);

The function argument is a pointer to a stream of type FILE. The function returns the code of the read character. If the end of file is reached or an error occurs, the EOF constant is returned.
Writing a character to a file:

fputc(character, stream);

The function's arguments are a character and a pointer to a stream of type FILE. The function returns the code of the read character.

The fscanf() and fprintf() functions are similar to the scanf() and printf() functions, but operate on data files and have a file pointer as their first argument.

fscanf(stream, "Input Format", arguments);
fprintf(stream, "Output Format", arguments);

The fgets() and fputs() functions are for string I/O, they are analogous to the gets() and puts() functions for working with files.

fgets(Pointer To String, Number Of Characters, Stream);

Characters are read from the stream until a newline character "\n" is read, which is included in the string, or until the end of the stream is EOF or the maximum number of characters has been read. The result is placed in a string pointer and terminated by the null character "\0". The function returns the address of the string.

fputs(Pointer To String, stream);

Copies a string to the stream from the current position. The terminating null character is not copied.
Example Enter a number and save it in the s1.txt file. Read the number from the s1.txt file, increase it by 3 and save it in the s2.txt file.

The I / O mechanism developed by , does not correspond to the generally accepted object-oriented programming style today, in addition, it actively uses pointer operations, which are considered potentially unsafe in modern secure code execution environments. An alternative for application development is the standard I/O class mechanism provided by the C++ language standard.

Opening files

The most commonly used classes are ifstream for reading, ofstream for writing, and fstream for modifying files.

All threaded I/O classes are indirectly derived from the common ancestor ios , fully inheriting its functionality. For example, the open_mode enumerated data member specifies the file open mode, which is defined as follows:

Enum open_mode ( app, binary, in, out, trunc, ate );

Below are the possible values ​​of the flags and their purpose.

For example, to open a file called test.txt to read binary data, you would write:

ifstream file; file.open("test.txt", ios::in | ios::binary);

The logical OR operator (|) allows you to compose a mode with any combination of flags. So that when opening a file by writing, you do not accidentally overwrite an existing file with the same name, you must use the following form:

offstream file; file.open("test.txt", ios::out | ios::app);

It is assumed that the appropriate header file is connected to the project:

#include

To check if the file was successfully opened, you can use the construction

If (!file) ( // Handling a file open error )

Inclusion and Extraction Operators

Overridden in file handling classes include operator (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

File<< "Это строка текста";

You can also write a text string in parts:

File<< "Это " << "строка " << "текста";

The endl statement ends the line input with a carriage return:

File<< "Это строка текста" << endl;

Using the include operator, it is easy to write the values ​​of variables or array elements to a file:

Ofstream file("Temp.txt"); char buff = "Text array contains variables"; int vx = 100; float pi = 3.14159; file<< buff << endl << vx << endl << pi << endl;

As a result of the code execution, three lines of the Temp.txt text file are generated:

Text array contains variables 100 3.14159

Note that the numeric values ​​are written to the file as text strings, not binary values.

extract operator(>>) does the opposite. It would seem that to extract the characters from the Temp.txt file written earlier, you need to write code like the following:

ifstream file("Temp.txt"); char buff; intvx; floatpi; file >> buff >> vx >> pi;

However, the extraction operator will stop at the first delimiter (space, tab, or newline) that it encounters. Thus, when parsing the sentence "Text array contains variables", only the word "Text" will be written to the buff array, the space is ignored, and the word "array" will become the value of the integer variable vx and the code execution will "go haywire" with an inevitable violation of the data structure. Next, when discussing the ifstream class, we will show how to correctly organize the reading of the file from the previous example.

ifstream class: reading files

As the name implies, the ifstream class is designed to input a file stream. The main methods of the class are listed below. Most of them are inherited from the istream class and overloaded with parent functionality. For example, the get function, depending on the call parameter, is able to read not only a single character, but also a character block.

Now it is clear how you need to modify the previous example so that using the data extraction operator gives the expected result:

ifstream file("Temp.txt"); char buff; intvx; floatpi; file.getline(buff, sizeof(buff)); file >> vx >> pi:

The getline method will read the first line of the file to the end, and the >> operator will assign values ​​to variables.

The following example shows adding data to a text file and then reading the entire file. The while (1) loop is used instead of while(!file2.eof()) for reasons discussed in .

#include #include using namespace std; int main() ( ofstream file; file.open("test.txt",ios::out|ios::app); if (!file) ( cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >>a; if (file2.eof()) break; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

The following example loops through reading lines from the file test.txt and displaying them on the console.

#include #include using namespace std; int main() ( ifstream file; // create a stream object file file.open("test.txt"); // open file for reading if (!file) return 1; // return on error opening char str; // static line buffer // Read and display lines in a loop until eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

This code under Windows OS also depends on the presence of a newline character in the last line of the file, it would be more reliable to do this:

While (1) ( if (file.eof()) break; file.getline(str, sizeof(str)); cout<< str << endl; }

Explicit calls to the open and close methods are optional. Indeed, calling the constructor with an argument allows you to open the file immediately, at the moment the file stream object is created:

ifstream file("test.txt");

Instead of the close method, you can use the delete operator, which will automatically call the file object's destructor and close the file. The while loop code provides proper end-of-file checking.

ofstream class: writing files

The ofstream class is designed to output data from a file stream. The main methods of this class are listed below.

The include operator described earlier is convenient for organizing writing to a text file:

Ofstream file("temp.txt"); if (!file) return; for (int i=1; i<=3; i++) file << "Строка " << i << endl; file.close();

Binaries

In principle, binary data is served like text data. The difference is that if binary data is written in a certain logical structure, then they must be read from the file into a variable of the same structure type.

The first parameter of the write and read methods (the address of the write/read block) must be of the type of a character pointer char * , so it is necessary to explicitly convert the type of the address of the void * structure. The second parameter specifies that the file's binary blocks have a constant byte size regardless of the actual record length. The following appendix gives an example of how to create and display data in a simple notebook. The records of the file are then read sequentially and displayed on the console.

#include #include #include using namespace std; struct Notes ( // data structure of the notebook char Name; // full name char Phone; // phone int Age; // age ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1= ("Grozny Ioann Vasilyevich", "not installed", 60 ); Notes Note2= ("Godunov Boris Fedorovich", "095-111-2233 ", 30 ); Notes Note3= ( "Peter Romanov ", "812-333-2211 ", 20 ); ofstream ofile("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof (Notes)); // 1st block ofile.write((char*)&Note2, sizeof(Notes)); // 2nd block ofile.write((char*)&Note3, sizeof(Notes)); / / 3rd block ofile.close(); // close the written file ifstream ifile("Notebook.dat", ios::binary); Notes Note; // structured variable char str; // static string buffer // Read and display lines in a loop until eof while (!ifile.read((char*)&Note, sizeof(Notes)).eof()) ( sprintf(str, "%s\tBody: %s\tAge: %d" , Note.Name, Note.Phone, Note.Age); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

As a result of executing this code, a binary file Notebook.dat is formed from three blocks of 80 bytes each (assuming that the characters are single-byte). Naturally, you can use other streaming methods and perform any operation on the fields of a particular data structure.

fstream class: random file access

Suppose that our notebook has accumulated 100 entries, and we want to count the 50th. Of course, you can organize a loop and read all the records from the first to the given one. Obviously a more targeted solution is to set the pos file position pointer directly to entry 50 and read it:

ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Notes); ifile seek(pos); // search for the 50th entry Notes Note; //Notes - the "record" structure described above ifile.read((char*)&Note, sizeof(Notes));

Such search operations are effective if the file consists of records of a known and constant size. To replace the contents of an arbitrary entry, you need to open the output stream in modify mode:

Ofstream ofile("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Notes); ofile seekp(pos); // search for the 50th note Notes Note50 = ("Yeltsin Boris Nikolaevich", "095-222-3322", 64); ofile.write((char*)&Note, sizeof(Notes)); // replacement

If you do not specify the ios::ate (or ios::app) flag, then when you open the Notebook.dat binary file, its previous contents will be erased!

Finally, it is possible to open a file concurrently for reading/writing, using the methods inherited by the fstream streaming class from its predecessors. Since the fstream class is derived from istream and ostream (parents of ifstream and ofstream respectively), all of the previously mentioned methods become available to the application.

The following example swaps the first and third entries in the Notebook.dat file.

#include #include #include using namespace std; struct Notes ( char Name; char Phone; int Age; ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1, Note3; // Open file for reading/writing simultaneously fstream file("Notebook.dat", ios::binary | ios::in | ios:: out); file.seekg(2 * sizeof(Notes)); // find and read Note3 file.read((char*)&Note3, sizeof(Notes)); file.seekg(0); // find and read Note1 file.read((char*)&Note1, sizeof(Notes)); file.seekg(0); // Note1<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

The ios::in and ios::out flags must be specified in the file object's constructor to allow concurrent read and write operations. As a result of executing this code, the first and third records of the Notebook.dat binary file will be swapped.

There are additional examples on the topic.

Top Related Articles