⭐ Advanced C language ⭐ ⅸ detailed explanation of document operation [ suggested attention + collection ]

Posted by insight on Tue, 05 Oct 2021 04:49:35 +0200

catalogue

Why use files

What is a file

Classification (from the perspective of file function)

file name

Opening and closing of files

field name pointer

fopen and fclose functions

Open method table

Sequential reading and writing of files

Sequential read-write function table

What is an input / output stream

fgetc/fgetc character read / write function

fgets/fputs - string read / write function

fscanf/fprintf format read / write function

sscanf/sprintf function

Comparison of scanf/printf, fscanf/fprintf and sscanf/sprintf functions

fread/fwrite block read / write function

Random reading and writing of files

fseek function

ftell function

rewind function

Text and binary files

Classification (according to the organization form of data)

Storage form of data in memory

Judgment of end of file reading

feof function

ferror function

Read end judgment direction  

file buffer

preface

  This chapter mainly explains:

  1. Master the file operation and use of C language
  2. Basic use of various functions for file operation

Why use files

In the previous article, we wrote the address book. The address book with file operation function can make the data persistent
That is, when the address book runs next time, the data we entered in the address book still exists. The data does not exist only when we actively delete the data
Note: using files, we can store the data directly on the hard disk of the computer to achieve data persistence

What is a file

  • Concept:
Files on disk

Classification (from the perspective of file function)

Program file
Include source program files (suffix: .c ) , Target file( windows Environment suffix is .obj ) , Executable program( windows The environment suffix is. exe )
data file
The content of the file is not necessarily the program, but the data read and written when the program runs, such as the file from which the program needs to read data or the file that outputs the content
Note: the input and output here is based on the terminal. The output is to input the data to the disk, and the input is to read the data from the disk to the memory

file name

  • The file name contains three parts:

File path + file name trunk + file suffix (for user identification and reference)

  • For example:
c:\code\test.txt
Note: the file ID is often referred to as the file name

Opening and closing of files

field name pointer

  • Concept:
Each used file opens up a corresponding file information area in the memory to store the relevant information of the file (such as file name, file status and current location of the file, etc.)
This information is stored in a structure variable. The structure type is declared by the system and named FILE
  • Example: the stdio.h header file provided by VS2013 compilation environment has the following file type declaration
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
       };
typedef struct _iobuf FILE;
  • be careful:
  1. The FILE types of different C compilers contain different contents, but they are similar
  2. Whenever a FILE is opened, the system will automatically create a variable of FILE structure according to the situation of the FILE and fill in the information in it (users do not need to care about details)
  3. Generally, a FILE pointer is used to maintain the variables of the FILE structure (easy to use)
  • Example: create a pointer variable of FILE *
FILE* pf;//File pointer variable

Note: the file associated with it can be found through the file pointer variable

  • Diagram:

fopen and fclose functions

  • Concept:
Files should be read and written first Open file (using fopen function) , after use Close the file (using the fclose function)
Note: when you open a file, a will be returned FILE* The pointer variable of points to the file, which is equivalent to establishing the relationship between the pointer and the file
  • Example:
//Open file
FILE * fopen ( const char * filename,//file name 
const char * mode//Open mode
 );
//Close file
int fclose ( FILE * stream //field name pointer
);

Open method table

fopen open file mode
File usage
meaning
If the specified file does not exist
"r" (read only)
To enter data, open an existing text file
error
"w" (write only)
To output data, open a text file
Create a new file
"a" (added)
Add data to the end of a text file
Create a new file
"rb" (read only)
To enter data, open a binary file
error
"wb" (write only)
To output data, open a binary file
Create a new file
"ab" (added)
Add data to the end of a binary file
error
"r+" (read and write)
To read and write, open a text file
error
"w+" (read and write)
A new file is recommended for reading and writing
Create a new file
"a+" (read and write)
Open a file and read and write at the end of the file
Create a new file
"rb+" (read and write)
Open a binary file for reading and writing
error
"wb+" (read and write)
Create a new binary file for reading and writing
Create a new file
"ab+" (read and write)
Open a binary file and read and write at the end of the file
Create a new file

Note: "r" means read; "w" means write; "a" means append; "+" means readable and writable to the file; "t" means text file (generally omitted); "b" means binary file (Note: if the type is not specified, the default is text file)

Generally speaking, learn to skillfully operate the first three

Example:
/* fopen fclose example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  //Open file
  pFile = fopen ("myfile.txt","w");
  //File operation
  if (pFile!=NULL)
 {
    fputs ("fopen example",pFile);
    //Close file
    fclose (pFile);
 }
  return 0; 
 }

Sequential reading and writing of files

Sequential read-write function table

function
Function name
Apply to
Character input function
fgetc
All input streams
Character output function
fputc
All output streams
Text line output function
fgets
All input streams
Text line output function
fputs
All output streams
Format input function
fscanf
All input streams
Format output function
fprintf
All output streams
Binary input
fread
file
Binary output
fwrite
file

Note: use these functions to include the header file < stdio. H >

What is an input / output stream

  • Input stream:

A stream that reads data from another device into memory

  • Output stream:

A stream that writes data out of memory to other devices

  • About flow diagram:

  • be careful:

As long as the C language program is run, three streams are opened by default:
stdin: standard input stream (corresponding to keyboard)
stdout: standard output stream (corresponding screen)
stderr: standard error flow (corresponding screen)
Note: the types of these three streams are FILE pointers of FILE * streams

fgetc/fgetc character read / write function

  • definition:
int fputc( int c,//Character (or corresponding ASCII code value)
 FILE *stream //File pointer (or stream)
);
int fgetc( FILE *stream );
  • be careful:
  1. The function of fputc is to output characters to a stream. The return type is int. when the function outputs characters successfully, it returns the corresponding ASCII code value of the characters. When the output fails, it returns EOF
  2. The fgetc function can obtain characters from the file stream. The return type is int. when the function inputs characters successfully, it returns the corresponding ASCII code value of the characters. When the input fails, it returns EOF

Note: every time the function runs once, the pointer of the stream (standard input stream or file stream) will point to the first address of the space after reading the content

  • Example:
	//Create and open files
	FILE* pf = fopen("test.txt", "w");//Open file read
	//Note: if there is a test.txt file in the file, you don't need to create it. If not, you will create the file first and then open the file in the corresponding way
	if (pf == NULL)
	{
		perror("fopen:");
		return;
	}
	char ch;
	//fgetc(stdin)==getchar()
	while ((ch = fgetc(stdin)) != EOF)
	{
		//Output to file stream
		fputc(ch, pf);
	}
	//Read data
	while (ch = fgetc(pf) != EOF)
	{
		//putchar(ch)==fputc(ch,stdout)
		putchar(ch);
	}
  • Special attention:

fgetc(stdin)==getchar();

putchar(ch)==fputc(ch,stdout);

fgets/fputs - string read / write function

  • definition:
char *fgets( char *string, int n, FILE *stream );

int fputs( const char *string, FILE *stream );
  • be careful:
  1. The fgets function reads a string from the stream to the corresponding storage location; The first parameter is the storage location of the obtained string; The second parameter is the maximum number of characters of the string to be read; The third parameter is the file pointer (file stream) of the file to be read. If the function reads successfully, it returns the address where the string is stored. Otherwise, it returns NULL (end of file / error encountered)
  2. The function of fputs is to output a string to a stream. The first parameter of the function is the written string (first address), the second parameter is a stream, and the return value of the function is int. when the function is written successfully, it returns a positive number, otherwise it returns EOF
  • Example:
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char str[] = "Hello world!";
	fputs(str, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}
int main()
{
	FILE* pf = fopen("data1.txt", "r");//Open file read
	if (pf == NULL)
    {
		perror("fopen");
		return 1;
	}
	char str[20] = { 0 };
	fgets(str, 5, pf);//Read the string in the file into arr
	                  //Note: 5 bytes are read here, including the character '\ 0'
    printf("%s\n", arr);//Print out the read string
	fclose(pf);
	pf = NULL;
	return 0;
}
  • Special attention:

fgets(str, stdin)==gets(str);
fputs(str, stdout)==puts(str);

fscanf/fprintf format read / write function

  •   definition:
int fscanf( FILE *stream, const char *format [, argument ]... );
int fprintf( FILE *stream, const char *format [, argument ]...);
  • be careful:
  1. The function of fscanf is to obtain the formatted data into the target stream. The first parameter of the function is a file stream (input source stream), the second parameter is the input parameter form (there can be multiple), and the third parameter of the function is the target of the input data
  2. The function of fprintf is to output formatted data to the target stream. The first parameter of the function is a file stream (target stream), the second parameter is the input parameter form (there can be multiple), and the third parameter of the function is the source of the input data
  • Example:
//Student information
struct student
{
	char name[20];
	char sex[5];
	int age;
	int score;
};
//roster
struct Register
{
	struct student data[5];
	int num;
}stu;num=0;
void ioinfo(char* str, char* way,struct Register*ptr)
{
	//Open file
	FILE* pf = fopen(str, way);
	if (pf == NULL)
	{
		perror("fopen:");
		return;
	}
	//Load data into memory
	for (int i = 0; i < ptr->num; i++)
	{
		fscanf(pf, "%s %s %d %d",&ptr->data[i].name, &ptr->data[i].sex, &ptr->data[i].age, &ptr->data[i].score);
	}
	//Display data
	for (int i = 0; i < ptr->num; i++)
	{
		printf("%s %s %d %d", ptr->data[i].name, ptr->data[i].sex, ptr->data[i].age, ptr->data[i].score);
	}
	//Write data
	printf("Enter the number of student data written\n");
	scanf("%d", &ptr->num);
	for (int i = 0; i < ptr->num; i++)
	{
		scanf("%s %s %d %d", &ptr->data[i].name, &ptr->data[i].sex, &ptr->data[i].age, &ptr->data[i].score);
	}
	//Import data to file
	for (int i = 0; i < ptr->num; i++)
	{
		fprintf(pf, "%s %s %d %d", &ptr->data[i].name, &ptr->data[i].sex, &ptr->data[i].age, &ptr->data[i].score);
	}
	fclose(pf);
	pf = NULL;
	return;
}
  • Special attention:

fscanf(stdin, "%d", &i)==scanf("%d",&i);
fprintf(stdout, "%d", i)==printf("%d",i);

sscanf/sprintf function

  • definition:
int sprintf( char *buffer, const char *format [, argument] ... );
int sscanf( const char *buffer, const char *format [, argument ] ... );
  • be careful:
  1. sprintf function can write a formatted data into the target address buffer in the form of string. The first parameter of the function is the target address converted into string, and the second parameter refers to fprintf or printf function (the parameters of the three are the same)
  2. The sscanf function can read formatted data from a string (buffer). The first parameter is the address of the read string, and the second parameter refers to the fscanf or scanf function
  • Example:
struct S
{
	char name[20];
	int age;
	char sex[5];
};
int main()
{
	struct S s = { "Zhang San",18,"male" };
	char buf[100] = { 0 };
	sprintf(buf, "%s %d %s", s.name, s.age, s.sex);
	printf("%s\n", buf);

	struct S s1 = { 0 };
	sscanf(buf, "%s %d %s", s1.name, &(s1.age), s1.sex);
	printf("%s %d %s", s1.name, s1.age, s1.sex);
	return 0;
}

Note: in fact, this is very similar to the sscanf/sprintf function and the fscanf/fprintf function, except that one is input and output to the character array and the other is input and output to the file stream

Comparison of scanf/printf, fscanf/fprintf and sscanf/sprintf functions

  • scanf/printf:

Formatted I/O functions for standard input and output streams

  • fscanf/fprintf:

Formatted I/O functions for all input and output streams

  • sscanf/sprintf:

Extract the formable data input from the string and convert the formatted data into string output

fread/fwrite block read / write function

  • definition:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
  • be careful:
  1. The function of fwrite function is to output data to the target stream in binary form. The first parameter is a pointer (the source address of the output data), the second parameter is the byte size of each output data, the third parameter is the maximum output times, and the fourth parameter is the target stream of data output, returning the complete number of actual output times
  2. The function of fread function is to input data from the source stream to the target address in binary form. The first parameter is a pointer (the target address of the input data), the second parameter is the byte size of each input data, the third parameter is the maximum input times, and the fourth parameter is the source stream of data input, returning the actual complete input times
  • Example:
//Address book (input / output data)

//Load address book data
void LoadContact(struct Contact*p)
{
	//rb: open a binary file as read-only
	FILE* pf = fopen("contact.txt","rb");
	if (pf == NULL)
	{
		perror("Loadcontact");
		return;
	} 
	//Save data temporarily
	struct Peoinfo tmp = { 0 };
	//fread: binary input (return 1 if the input data is complete, otherwise return 0)
	while (fread(&tmp, sizeof(struct Peoinfo), 1, pf))
	{
		//Judge whether capacity increase is required during input
		CheakContact(p);
		p->data[p->sz] = tmp;
		p->sz++;
	}
	//release
	fclose(pf);
	pf = NULL;
	return;
}

//Save address book data
void SaveContact(struct Contact* p)
{
	//fopen function: finds the specified file and returns the address of the file
	//wb: open in write only mode (to output data, open a binary file)
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		//If the opening fails, an error message is printed
		perror("SaveContact");
		return;
	}
	for (int i = 0; i < p->sz; i++)
	{
		//fwrite: binary output
		fwrite(p->data+i, sizeof(struct Peoinfo), 1, pf);
	}
	//Release after pf is used up
	fclose(pf);
	pf = NULL;
	return;
}

Random reading and writing of files

fseek function

  • effect:
Locate the file pointer according to the position and offset of the file pointer
Note: whenever the data of a file is read, the file pointer will point to the next spatial address
  • definition:
int fseek ( FILE * stream, long int offset, int origin );
  • be careful:

The first parameter is the file stream, the second is the offset position size, and the third parameter is the start position

  • regulations:

File start location: SEEK_SET (the value of offset is positive)

Current file location: SEEK_CUR (the value of offset can be positive or negative)

File end location: SEEK_END (offset value is negative)

  • Example:
/* fseek example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
//Relative path (find and create in current file)
  pFile = fopen ( "example.txt" , "wb" );
  fputs ( "This is an apple." , pFile );
  fseek ( pFile , 9 , SEEK_SET );
  fputs ( " sam" , pFile );
  fclose ( pFile );
  return 0; 
}
  • result:

ftell function

  • effect:

Returns the offset of the file pointer from the starting position

  • definition:
long int ftell ( FILE * stream );
  • Example:
/* ftell example : getting size of a file */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  long size;
  pFile = fopen ("myfile.txt","rb");
  if (pFile==NULL) 
  perror ("Error opening file");
  else
 {
//Gets the file byte size
    fseek (pFile, 0, SEEK_END);   // non-portable
    size=ftell (pFile);
    fclose (pFile);
    printf ("Size of myfile.txt: %ld bytes.\n",size);
 }
  return 0; 
}

rewind function

  • effect:
Returns the position of the file pointer to the starting position of the file
  • definition:
void rewind ( FILE * stream );
  • Example:
/* rewind example */
#include <stdio.h>
int main ()
{
  int n;
  FILE * pFile;
  char buffer [27];
  pFile = fopen ("myfile.txt","w+");
  for ( n='A' ; n<='Z' ; n++)
    fputc ( n, pFile);
//Return to the starting position and read again
  rewind (pFile);
  fread (buffer,1,26,pFile);
  fclose (pFile);
//'\ 0' will not be added after reading (the terminator is required for puts)
  buffer[26]='\0';
  puts (buffer);
  return 0; 
}

Text and binary files

Classification (according to the organization form of data)

Binary file

Data is stored in binary form in memory and output to external memory without conversion. If it is required to be stored in external memory (it can only be understood by using binary compiler if it is not understood)

text file

It is stored in ASCII code and needs to be converted before storage (it can be understood)

Storage form of data in memory

All characters are in ASCII Formal storage, numerical data can be used ASCII Formal storage, or binary storage
  • Example: integer 10000

#include <stdio.h>
int main()
{
 int a = 10000;
 FILE* pf = fopen("test.txt", "wb");
 fwrite(&a, 4, 1, pf);//Write to file in binary form
 fclose(pf);
 pf = NULL;
 return 0; 
}

Judgment of end of file reading

feof function

Function: used to judge whether the end of the file is encountered (if the file pointer is the end of the file, it returns non-zero, otherwise it returns zero)

ferror function

Function: used to judge whether an error is encountered and the reading fails (if an error is encountered, it returns non-zero, otherwise it returns zero)

Read end judgment direction  

Whether the text file reading is completed, and judge whether the return value is EOF (fgetc) or NULL (fgets)
  • For example:
fgetc Judge whether it is EOF 
fgets Judge whether the return value is NULL 
Judge whether the return value is less than the actual number of binary files to be read
  • For example:
fread Judge whether the return value is less than the actual number to be read
  • Example 1: text file
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int c; // Note: int, not char, requires EOF processing
    FILE* fp = fopen("test.txt", "r");
    if(!fp) {
        perror("File opening failed");
        return EXIT_FAILURE;
   }
 //fgetc will return EOF when reading fails or when the file ends
    while ((c = fgetc(fp)) != EOF) // Standard C I/O read file cycle
   { 
       putchar(c);
   }
//Judge why it ended
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
    fclose(fp);
}
  • Example 2: binary file
#include <stdio.h>
enum { SIZE = 5 };
int main(void) {
    double a[SIZE] = {1.,2.,3.,4.,5.};
    FILE *fp = fopen("test.bin", "wb"); // Binary mode must be used
    fwrite(a, sizeof *a, SIZE, fp); // Write an array of double
    fclose(fp);
    double b[SIZE];
    fp = fopen("test.bin","rb");
    size_t ret_code = fread(b, sizeof *b, SIZE, fp); // Read array of double
    if(ret_code == SIZE) {
        puts("Array read successfully, contents: ");
        for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]);
        putchar('\n');
   } else { 
       // error handling
       if (feof(fp))
          printf("Error reading test.bin: unexpected end of file\n");
       else if (ferror(fp)) {
           perror("Error reading test.bin");
       }
   }
    fclose(fp);
}

file buffer

  • Concept:
ANSIC Standard adoption " Buffered file system " The so-called buffer file system refers to that the system automatically opens up a block for each file in use in the program in memory“ file buffer "
The data output from memory to disk will be sent to the buffer in memory first, and then sent to the disk together after the buffer is filled. If the data is read from the disk to the computer, the data will be read from the disk file and input into the memory buffer (full buffer), and then the data will be sent to the program data area (program variables, etc.) one by one from the buffer
Note: the buffer size is based on C Compilation system determined
  •   Example: you can test by yourself
#include <stdio.h>
#include <windows.h>
//VS2013 WIN10 environment test
int main()
{
 FILE*pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//Put the code in the output buffer first
 printf("Sleep for 10 seconds-The data has been written. Open it test.txt File, no content found in the file\n");
 Sleep(10000);
 printf("refresh buffer \n");
 fflush(pf);//When the buffer is refreshed, the data of the output buffer is written to the file (disk)
 //Note: fflush cannot be used on higher version VS
 printf("Sleep for another 10 seconds-At this point, open again test.txt File, the file has content\n");
 Sleep(10000);
 fclose(pf);
 //Note: fclose also flushes the buffer when closing the file
 pf = NULL;
 return 0; 
}
  • Conclusion:
When operating files in C language, you need to refresh the buffer or close the file at the end of the file operation (if you don't do it, you may lose data)

Topics: C