C file operation 1: how to write and read? How to use the six combination parameters of fopen?

File operation in C language, that is, file opening, file writing, file reading, file closing, etc.

When using these functions, you need to understand their basic usage rules, such as:

Before reading or writing a file, you must first use the fopen function to open the file.

When using fopen to open, you should also specify the parameters for opening the file, whether to read or write? If you don't pay attention to these parameters, such as directly using the "w" parameter to open an existing file, the contents will be cleared first. If you still want the contents of the previous file, they will also be cleared!

File operation basis function

fopen

To read and write files, the first step is to use the fopen() function

The fopen() function is used to open the file in the specified path and get the pointer to the file

Function prototype:

/** @func:  fopen
*   @brief: Open file
*   @para:  [path]:File path, such as: "E:\Test\test.txt"
*           [mode]:File opening method (r w a r+ w+ a+ rb wb ab... See the table below for details)
*   @return:If the file is opened successfully, the file pointer to the stream will be returned
*           If the file fails to open, NULL is returned and the error code is stored in errno
*/
FILE * fopen(const char * path,const char * mode);

Parameters of fopen opening mode

There are 6 symbols for the parameters of opening the file, including 2 parts. The first part specifies whether to read or write (r\w\a), and the second part specifies whether to supplement the first part (t/b / +)

  • Parameter part 1 (r\w\a)
Part 1 charactersmeaningexplain
rreadRead only (open file), file must exist
wwriteWrite only (create file). If the file already exists, the file will be emptied first
aappendAppend write at the end. If the file does not exist, create it first
  • Parameter part 2 (t\b \ +)
    |Part 2 character | meaning | interpretation|
    | ----------- | ---------- | -------------------- |
    |t | text | reading and writing text files|
    |b | binary | read and write binary files|
    |+ | read/write | can read and write|

be careful:

The first part of the parameter is required, and the second part can be omitted, but after omission, it will have its default meaning

If it is not specified whether to read text or binary, the default is to read text file

Default rule:

"r" = "rt", Because it's on by default text
"w" = "wt", Because it's on by default text
"a" = "at", Because it's on by default text
"r+" = "rt+", Because it's on by default text
"w+" = "wt+", Because it's on by default text
"a+" = "at+", Because it's on by default text

reflection:

  • Question 1: is there any difference between r + and w +?

r stands for reading and w stands for writing. Both add a +. It means that you can read and write. It seems that the function is the same

However, the difference lies in the r and w in part 1. One is that the file must exist, and the other is that if it does not exist, it will be created first

  • Question 2: is there any difference between w and w +? Is there any difference between a and a +?

w indicates erase write, a indicates additional write, and a + is added to give them the function of reading

Since both w and a can be written, can't they be read? Do you need to add a + to read? yes!

fread

Function prototype:

/** @func:  fread
*   @brief: Read from file
*   @para:  [buffer]:Pointer to data block
*           [size]:The size of each data, in bytes (for example, sizeof(int) is 4)
*           [count]:Number of data
*           [stream]:File pointer, such as fp
*   @return:Number of actual reads
*/
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);

The return value of fread varies with the call format:

  • Call format 1: fread(buf,sizeof(buf),1,fp);, If the entire buf data is read as one data, the number of reads is one

    Reading succeeded. The return value is 1

  • Call format 2: fread(buf,1,sizeof(buf),fp);, If 1Byte is read as one piece of data, the number of reads is sizeof(buf)

    The number of actually written data returned after successful reading (unit: Byte)

fwrite

The fwrite() function is used to write the data in the memory area to the local text

Function prototype:

/** @func:  fwrite
*   @brief: Write to file
*   @para:  [buffer]:Pointer to data block
*           [size]:The size of each data, in bytes (for example, sizeof(int) is 4)
*           [count]:Number of data
*           [stream]:File pointer, such as fp
*   @return:Number of actual writes
*/
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

The return value of fwrite varies with the calling format:

  • Call format 1: fwrite(buf,sizeof(buf),1,fp);, If the entire buf data is written as one data, the number of writes is 1

    The return value of successful writing is 1

  • Call format 2: fwrite(buf,1,sizeof(buf),fp);, If 1Byte is written as one piece of data, the number of writes is sizeof(buf)

If it is written successfully, the number of data actually written is returned (unit: Byte)

fclose

After writing the data, call fclose() to close the stream. If the stream is not closed, the file pointer will point to the pointer of the next data position to be written or read every time the data is read or written.

Function prototype:

/** @func:  fclose
*   @brief: Close file
*   @para:  [stream]:File pointer, such as fp
*   @return:0 is returned for successful closing and EOF is returned for failure closing
*/
int fclose( FILE *stream );

Use example

Basic example

Open & write

Tips:

When applying for an area with malloc function, it is a char * area applied for. Any type of data can be loaded after forced type conversion

#include <stdio.h>
#include <stdlib.h>

#define DATA_SIZE 100
 
int main()
{
    unsigned char *pRawData = NULL;
    int *pData = NULL;
    
    /*Apply for a piece of memory using malloc*/
    pRawData = (unsigned char *)malloc(sizeof(int) * DATA_SIZE);
    /*Cast the block memory to unsigned int*/
    pData = (int *) pRawData;
    
    /*Assign a value to this block of memory */
    int i = 0;
    for(i=0; i<DATA_SIZE; i++)
    {
        pData[i] = i; 
    }
    
    /*open*/
    FILE *fp = fopen("../test1.bin","wb");
    if(NULL == fp)
    {
        printf("open file fail\r\n");
        goto end;
    }
    
    /*write in*/
    size_t cnt = fwrite(pData, sizeof(int), DATA_SIZE, fp);
    if(DATA_SIZE != cnt)
    {
        printf("write file fail\r\n");
        fclose(fp);
        goto end;
    }
    
    /*close*/
    fclose(fp);
    printf("file write ok\r\n");
    
 end:
    free(pRawData);/*malloc free after use*/
    system("pause");
    
    return 0;
}

Open & read

be careful:

Write in binary form and read in binary form! Otherwise, wrong data will be read

#include <stdio.h>
#include <stdlib.h>

#define DATA_SIZE 100
 
int main()
{
    int pData[DATA_SIZE];
    
    /*open*/
    FILE *fp = fopen("../test1.bin","rb");/*Bin is written and bin must be read*/
    if(NULL == fp)
    {
        printf("open file fail\r\n");
        goto end;
    }
    
    /*read*/
    size_t cnt = fread(pData, sizeof(int), DATA_SIZE, fp);
    if(DATA_SIZE != cnt)
    {
        printf("read file fail, read size:%d\r\n", cnt);
        fclose(fp);
        goto end;
    }
    printf("data[30]:%d\r\n", pData[30]);/*Print out one of the data*/
    
    /*close*/
    fclose(fp);
    printf("file read ok\r\n");
    
 end:
    system("pause");
    
    return 0;
}

Special examples

Write structure

/*Define structure*/
typedef struct
{
	char name[256];
	unsigned int page;
	float price;	
}BOOK;
 
/*Instantiate an object declaration*/
BOOK book1 = {
    .name = "C Language foundation",
    .page = 320,
    .price = 25.0,
};

Write mode:

/*open*/
FILE *fp1 = fopen("../test2.bin","wb");
if(NULL == fp1)
{
    printf("open file fail\r\n");
    goto end;
}

/*write in*/
size_t cnt1 = fwrite(&book1, 1, sizeof(BOOK), fp1);
if(sizeof(BOOK) != cnt1)
{
    printf("write file fail\r\n");
    fclose(fp1);
    goto end;
}

Read mode:

/*open*/
FILE *fp2 = fopen("../test2.bin","rb");
if(NULL == fp2)
{
    printf("open file fail\r\n");
    goto end;
}

/*read*/
size_t cnt2 = fread(&myBook, 1, sizeof(BOOK), fp2);
if(sizeof(BOOK) != cnt2)
{
    printf("read file fail\r\n");
    fclose(fp2);    
    goto end;
}
printf("myBook info: name:%s, page:%d, price:%.2f\r\n",
       myBook.name, myBook.page, myBook.price);

summary

Open the file (fopen) before reading (fread) or writing (fwrite).

After reading (fread) or writing (fwrite) the file, close (fclose) the file.

When opening (fopen) files, pay special attention to the specification of open parameters.

When opening a file with the r parameter, the file must exist.

When opening a file with w parameter, the file will be emptied first. If the file does not exist, it will be created first.

When opening a file with a parameter, the written content will be added at the end of the file. If the file does not exist, it will be created first.

When a file is opened with the b parameter, a binary file is opened.

When a file is opened with the t parameter, or if b or t is not specified, a text file is opened.

When the file is opened, it has the function of reading + writing.

Keywords: C

Added by thinkgfx on Sat, 19 Feb 2022 18:18:33 +0200