The file structure body __c language in C language

Source: Internet
Author: User
Tags fread stdin terminates file permissions

The data in memory is temporary and will be lost when the program ends. In order to save a large amount of data in perpetuity, the C language provides the operation of the file.

1. Files and Streams

c simply stream each file as a sequential byte (as shown in the following figure). Each file ends with a file terminator or ends at a specific number of bytes, which can be stored in a system-maintained management data structure. When you open a file, you establish a relationship with the file. When you start executing the program, 3 files and associated streams are automatically opened: standard input stream, standard output stream, and standard error. Streams provide a communication channel for files and programs. For example, a standard input stream allows a program to read data from the keyboard, whereas a standard output stream allows the program to output data on the screen. Opening a file returns a pointer to the file structure (defined in stdio.h) that contains the information that is used to process the document, that is, the structure contains the file descriptor. The file descriptor is an operating system array (the index of the Open file list). Each array element consists of a file control block (FCB, the file controls blocks) that the operating system uses to manage specific files. Standard input, standard output, and standard errors are handled using the file pointers stdin, stdout, and stderr.

2, C language file operation of the underlying implementation of the introduction

2.1 File Structure Body

In the stdio.h header file of the C language, a struct file is defined for the operation of the document. In this way, we return a file pointer (a pointer to the file structure body) through fopen to file operations. You can view the definition of the file structure in the header file of Stdio.h (under the Include folder in the Visual Studio installation directory) as follows:

[CPP] view plaincopy



struct _iobuf {char *_ptr;           int _cnt;           Char *_base;           int _flag;           int _file;           int _charbuf;           int _bufsiz;           Char *_tmpfname;   }; typedef struct _IOBUF FILE;

Implementation of 2.2 C language file management

The C program manages each file with a different filename structure. Programmers can use files, but they don't need to know the details of the file structure. In fact, the file structure is an indirect operating system file control block (FCB) to implement the operation of the files, as shown in the following figure:

The _file in the figure above is actually a descriptor, as an integer entering the index of the Open File table.

2.3 Introduction to operating system file management

As can be seen from the figure in 2.2, the C language can indirectly manipulate the file control block (FCB) through the filename structure. In order to deepen understanding of these, this is popular science under the operating system to open the file management.

Files are stored on a physical disk, including file control blocks (FCB) and data blocks. File control blocks typically include file permissions, dates (create, read, modify), owner, file size, block information. Data blocks are used to store actual content. For open files, the operating system is managed in this way: The system maintains two tables, one is the system-level Open File table "points to I", and one is the process-level Open File table (one for each process) "pointing to the file structure." The system-level Open File Table duplicates information about the file control block, and so on, the process-level Open File table holds pointers to system-level file tables and other information. System-level File table Each item holds a counter, that is, the number of times the file was opened. When we first open a file, the system starts by looking at whether the file is already in the system-level file table, or if it is not, creates the information, otherwise the counter adds 1. When we close a file, the corresponding count is reduced by 1, and when it is reduced to 0 o'clock, the system deletes the items in the system-level file table. When a process opens a file, an entry is added to the process-level file table. Information for each item includes the current file offset (the location of the read-write file), access permissions, and a pointer to the corresponding file entry in the system-level file table. Each entry in the system-level file table is identified by a file descriptor (a non-negative integer).

Contact 2.2 and 2.3 above, you can find that this should be: the _file member in the file structure should point to the process-level Open File table, and then open the file table through the process level to find the system-level Open File table, and then through the FCB to manipulate the files on the physical disk.

2.4 Examples of file operations

[CPP] view plaincopy



#include  <stdio.h>   void main ()  {       FILE  * fp1;       FILE * fp2;   &NBSP;&NBSP;&NBSP;&NBSP;FP1  = fopen ("Filetest.cpp", "R");       fp2 = fopen ("Filetest.cpp "," R ");       char buffer[256];       fscanf ( FP1, "%s", buffer);       printf ("%s\n", buffer);       &NBSP;FSCANF (FP2, "%s", buffer);       printf ("%s\n", buffer);        printf ("FP1" (filetest.cpp):%d\n ", Fp1->_file);       printf (" FP2 (filetest.cpp):%d\n ", Fp2->_file);       printf (" stdin:%d\n ", Stdin->_file );       printf ("stdout:%d\n", Stdout->_file);        printf("stderr:%d\n", Stderr->_file);  }  

The contents of the Filetest.cpp are as follows:

[CPP] view plaincopy



#include <stdio.h> int main () {printf ("Hello world!\n");   return 0; }

The results of the operation are as follows:

This program can be seen that every time you open a file, even if the same file is opened more than once, the process-level Open File table should be added a record. If you are opening the same file, the multiple records correspond to the same physical disk file. Because every time that you open a file is done by opening a different record in the file table at the process level, in this way, the equivalent of each open file is relatively independent, which is the result of the above program, two times the result of the read file is the same (rather than the second read from the first end of the position).

In addition, it can be seen that when the program is running, the default three streams are open stdin,stdout and stderr, and their _file descriptors are 0, 1, and 2, respectively. You can also see that the file descriptor that the program opens is incremented in turn from 3.

3, sequential access to the file

3.1 Write files in order

Let's look at one example:

[CPP] view plaincopy



#include  <stdio.h>   int main ()    {       int  account;//account        char name[30];//account name         double balance;//Balance           FILE *cfPtr;       if  ((Cfptr=fopen ("Clients.dat", "W") ==null)        {            printf ("file could not be  opened.\n ");       }       else        {           printf ("enter the  account, name and the balance:\n ");            printf ("enter eof to end input.\n");            printf ("? ");           scanf ("%d%s%lf", &account, name,&balance);           while (!feof (stdin))            {                fprintf (Cfptr, "%d %s %.2f\n", account,name,balance);                printf ("? ");       &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SCANF ("%d%s%lf", &account,name,&balance);            }            fclose (cfptr);       }       return 0;   }  

Run Result:

As you can see from the example above, writing to a file takes about two steps: Defining the file pointer and opening the file. function fopen has two parameters: file name and file open mode. File is used for writing when opening the mode ' W ' description file. If a file that is opened in write mode does not exist, Fopen creates the file. If you open an existing file to write, the original contents of the file are discarded without warning. In the program, the IF statement is used to determine whether the file pointer cfptr is null (fopen return value when the file is not successfully opened). If it is null, the error message is output, and the program terminates. Otherwise, the input is processed and written to the file.

Foef (stdin) is used to determine whether the user entered a file terminator from standard input. The file Terminator notifies the program that no other data can be processed. The FOEF parameter is a file pointer to whether the test is a filename terminator. Once the file terminator is entered, the function returns a value other than 0, otherwise the function returns 0. The program continues to perform a while loop when no file terminator is entered.

fprintf (Cfptr, "%d%s%.2f\n", account,name,balance); Write data to File Clients.dat. The data can be extracted later by the program used to read the file. function fprintf is equivalent to printf, except that fprintf also needs a pointer to a file, all data is written to this file.

After the user input file is finished, the program closes the Clients.dat file with Fclose and ends the run. The function fclose also receives the file pointer as a parameter. If the function fclose is not explicitly invoked, the operating system usually closes the file later at the end of the program execution. This is an example of "housekeeping" for the operating system, but it may cause unpredictable problems, so be sure to close the file after the end of use.

3.2 File Open mode

Mode Description
R Open the file for reading.
W Creates a file for writing. If the file already exists, the current content is deleted.
A Append, open or create a file to write at the end of the file.
r+ Open the file for update (read and write).
w+ Create a file to update. If the file already exists, the current content is deleted.
A + Append, open or create a file to update and write at the end of the file.

3.3 Sequential Read files

The following example reads the file that was written to the data generated in the previous example. [CPP] view plaincopy



#include  <stdio.h>   int main ()    {       int  account;//account        char name[30];//account name         double balance;//Balance           FILE *cfPtr;       if  ((Cfptr=fopen ("Clients.dat", "R") ==null)        {            printf ("file could not be  opened.\n ");       }       else        {           printf ("%-10s%-13s%s\n", " Account "," Name "," Balance ");           fscanf (cfptr,"%d%s%lf ", &account,name,&balance);           while (!feof (CFPTR) )           {                printf ("%-10d%-13s%lf\n", account,name,balance);        &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;FSCANF (Cfptr, "%d%s%lf", &account,&name,&balance);            }            fclose (cfptr);       }       return  0;  }  

Run Result:

In the example above, you can open a file to read data by simply turning the file opening mode from W to R in the first example.

Similarly, fscanf (cfptr, "%d%s%lf", &account,name,&balance); The function reads a record from the file. function fscanf and function scanf equivalence, just fscanf receive the file pointer from which to read the data as parameters. When the preceding statement is executed for the first time, account's value of 100,name is Jones, and balance equals 24.98. Each time the second FSCANF statement is executed, another record is read from the file, and Account,name and balance will have a new value. When the file end location is reached, the file is closed and the program terminates.

To retrieve data sequentially from a file, the program usually reads from the beginning of the file and reads all the data continuously until the desired data is found. During program execution, it is possible to process the data in the file more than once (from the beginning of the file to process the data again). This is where the function rewind (cfptr) is used, which enables the program's file position pointer (which indicates the location of the next byte to be read or written in the file) to be reset to the beginning of the file (that is, a byte with an offset of 0). Note that the file location pointer is not a pointer, it is an integer value for the next read or write location in the specified file, sometimes called a file offset, and is a member of the file structure.

4. Random Access to files

The length of the record created by the formatted input function fprintf in the file is not exactly the same. However, in random access files, the length of a single record is usually fixed and can be accessed directly (faster) without the need to find it through other records. This makes random file access suitable for aircraft booking systems, banking systems, point-of-sale systems, and other transaction processing systems that require quick access to specific data. There are many ways to implement random access files, but here we will limit the scope of the discussion to simple methods that use fixed-length records.

Function Fwrite writes a specified number of bytes starting at a specific location in memory to the file location specified by the file location pointer, and the function fread copies the specified number of bytes to the specified memory location from the file location specified by the file location pointer. Fwrite and Fread can read an array of data from a disk and write an array of data to the disk. The third parameter of Fread and Fwrite is the number of array elements read from or written to disk.

File handlers rarely write fields to the file. Typically, they write one struct at a time.

4.1 Creating random-access files

[CPP] view plaincopy



#include <stdio.h>   struct clientdata   {       int  acctNum;       char lastName[15];        char firstname[10];       double balance;  };   int  main ()    {       int i;        Struct clientdata blankclient={0, "", "",0.0};       FILE *cfPtr;        if  ((Cfptr = fopen ("Credit.dat", "WB") == null)         {           printf ("file  could not be opened.\n ");       }        else       {           for   (i=1;i<=100;i++)            {                fwrite (&blankclient,sizeof (struct  Clientdata), 1,cfptr);           }            fclose (cfptr);       }        return 0;  }  

Fwrite (&blankclient,sizeof (struct clientdata), 1,cfptr); is used to write a block of data to the file, which writes the size to Cfptr in the file that the sizeof points to (struct CLIENTDATA) Structure of blankclient. Of course, you can also write multiple elements of an array of objects, just pass the array name to the first argument, and write the number of elements you want to write to the third argument.

4.2 Randomly write data to random access files

[CPP] view plaincopy



#include <stdio.h>   struct clientdata   {       int  acctNum;       char lastName[15];        char firstname[10];       double balance;  };   int  main ()    {       int i;        Struct clientdata client={0, "", "",0.0};       FILE *cfPtr;        if  ((Cfptr = fopen ("Credit.dat", "rb+") == null)        {           printf ("File could  not be opened.\n ");       }        else       {           printf (" EntEr account number (1 to 100, 0 to end input): \ n ");     &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SCANF ("%d", &client.acctnum);            while  (client.acctnum!=0)             {               printf ("Enter  lastname, firstname, balance\n ");             &NBSP;&NBSP;&NBSP;FSCANF (stdin, "%s%s%lf", Client.lastname,client.firstname,&client.balance);               //to locate user-specified records      in Files            fseek (Cfptr, (client.acctNum-1) *sizeof (struct  clientdata), Seek_set);                //writes user-specified information to a file               fwrite (&client,sizeof ( Struct clientdata), 1,cfptr);                   //Enter next account                 printf ("enter account number:\n");           &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SCANF ("%d", &client.acctnum);            }           fclose (cfptr);        }       return 0;  }  

Run Result:

Fseek (Cfptr, (client.acctnum-1) *sizeof (struct clientdata), seek_set); Moves the position pointer of the file referenced by Cfptr to the CLIENT.ACCT

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.