The last chapter introduces the basic functions of C language file operation, fopen, fwrite, fread, fclose. These can only be read and written from the file header or appended to the file tail.

This paper introduces the method of random position reading and writing in the file, will introduce fseek, ftell, rewind.

In addition, several character reading and writing functions are introduced: fputs, fgets, fpritf, and fscanf, which are used when writing test code.

File random position read and write basic function

Random position reading and writing of files can be done by fseek, ftell and rewind functions

fseek

Fseek is used to set the file read/write position of the stream to a given offset

SeeK means “seeK” in Chinese.

Function prototype:

/** @func: fseek * @brief: Set the file read/write position of the stream to the given offset * @para: [fp]: file pointer * [offset]: indicates the offset, indicating the number of bytes moved. A positive number indicates the positive (end) offset, and a negative number indicates the negative (beginning) offset. * [from]: indicates where the offset starts from in the file. Return 0 (fp will point to from, offset by one byte) * on failure, return -1 and set the value of errno. For example, if offset exceeds the size of the file itself, the position to which FP points is */ will not be changed
int fseek(FILE *fp,long offset,int from);
Copy the code

From Specifies the value of the parameter

The starting point The symbol The figures show that the
The file begins SEEK_SET 0
The current position SEEK_CUR 1
The end of the file SEEK_END 2

Such as:

  • Move the read/write position to the beginning of the file
fseek(fp, 0L, SEEK_SET)
Copy the code
  • Move the read/write position to the end of the file
fseek(fp,0L,SEEK_END);
Copy the code
  • Move the read/write position to 100 bytes from the beginning of the file
fseek(fp,100L,SEEK_SET);
Copy the code
  • Move the read/write position to 100 bytes from the current file location
fseek(fp,100L,SEEK_CUR);
Copy the code
  • Return the read/write position to 100 bytes from the end of the file (offset negative indicates moving toward the beginning)
fseek(fp,-100L,SEEK_END);
Copy the code

Note:

The fseek function is generally used for binary files, but can also be used for text files.

When the fseek function operates on a text file, be aware of carriage return line feeds.

Because in general browsing tools (such as UltraEdit), the carriage return line is treated as two characters 0x0D and 0x0A, but the real file read and write and location is handled according to a character 0x0A.

This clearing can be done by reading the entire file into memory and then manually inserting 0x0D into memory.

ftell

The fseek function returns only whether the result of the execution was successful and does not return the read or write location of the file

To get the read/write location of the current file, you also need to use the ftell function to get it

Function prototype:

/** @func: ftell * @brief: Gets the offset of the current position pointer relative to the beginning of the file * @para: [fp]: file pointer * @return: */
long ftell(FILE *fp);
Copy the code

The main function of FELL is to obtain the current read/write location. When accessing files randomly, it is difficult to determine the current location of the file because the file location is frequently moved back and forth.

After moving the position using the fseek function, it is very easy to determine the current position of the file by calling the ftell function.

A small application of Fell: getting the length of a file

If you want to get the length of the file, you can record the current read/write position with ftell, then move it to the end, and then use ftell to get the position from the end of the file to the head, which is the length of the file. After obtaining the degree, the read and write position can be restored using Fseek.

long getFileLength(FILE *fp)
{
    long curPos=0L;/* The current position of the file pointer position */
    long len=0L;
    curPos = ftell(fp);/* Record the current position of the file pointer */
    fseek(fp, 0L, SEEK_END);/* Move read/write position to end of file */
    len = ftell(fp);/* Get the length from the end of the file to the beginning of the file */
    fseek(fp, curPos, SEEK_SET);/* Move the read/write position back to the previous position */
    return len;
}
Copy the code

The corresponding design idea of the code is as follows:

rewind

Rewind means “to go back” in Chinese.

The rewind function is used to repoint the position pointer inside a file to the starting position of a stream (data stream or file).

Note that the “pointer” is not a file pointer, but a position pointer inside the file. That is, as a file is read or written, the file’s position pointer (pointing to the current read or write byte) moves backward. The file pointer points to the entire file and does not change unless reassigned.

Function prototype:

/** @func: rewind * @brief: rewind the position pointer inside a file to the starting position of a stream (data stream or file) * @para: [fp]: file pointer * @return: none */
void rewind(FILE *fp);
Copy the code

Since the rewind function does not return a value, it is difficult to determine whether rewind(FP) was successfully executed.

Therefore, replace the Rewind function with fseek whenever possible to verify that the flow has been successfully wound

Here are a few more character reading and writing functions: fputs, fgets, fpritf, and fscanf, which are used when writing test code.

File read write string

fputs

The fputs function is used to write a line of string to a file

Function prototype:

/** @func: fputs * @brief: writes a string to a file * @para: [STR]: string to be written * [fp]: file pointer * @return: writes successfully, returns a non-negative number * writes failed, returns EOF */
int fputs( char *str, FILE *fp );
Copy the code

fgets

The fgets function reads a string from a specified file and saves it into an array of characters

Function prototype:

/** @func: fgets * @brief: reads a string from the specified file and saves it in a character array * @para: [STR]: character array * [n]: number of characters to read * [fp]: file pointer * @return: read success, return the first address of character array, that is, STR * failed to read, return NULL */
char *fgets ( char *str, int n, FILE *fp );
Copy the code

fprintf

Function prototype:

/** @func: fprintf * @brief: writes a formatted string to a file * @para: [fp]: file pointer * [format]: format string, text to be written to FP * @return: write success, returns the number of characters written * write failure, returns negative */
int fprintf(FILE *fp, const char *format, ...)
Copy the code

Usage:

FILE *fp = fopen ("test.txt"."w+");
char *str = "xxpcb.gitee.io";
int num = Awesome!;
fprintf(fp, "%s %d", str, num);
fclose(fp);
Copy the code

fscanf

Function prototype:

/** @func: fscanf * @brief: read a formatted string from a file * @para: [fp]: file pointer * [format]: format string, read from fp * @return: read success, return number of characters read * read failure, return negative */
int fscanf(FILE *fp, const char *format, ...)
Copy the code

Usage:

FILE *fp = fopen ("test.txt"."r");
char str[64]
int num;
fscanf(fp, "%s %d", str, num);
fclose(fp);
Copy the code

Use the sample

The following test program uses the fputs function to write the string “Hello world”, then uses the fseek function to move the read and write position to the sixth character from the beginning of the file, and then uses the fputs function to write the string “xxpcb.github. IO”. Overwrite at the specified location. Finally, use the fgets function to retrieve what was written to the file.

#include <stdio.h>
#define N 100

int main (a)
{ 
    Open / * * /
    FILE *fp = fopen(".. /test-futs.txt"."wt+");/* Open a file */
    if(NULL == fp)
    {
        printf("open file fail\r\n");
        goto end;
    }
    
    / * write * /
    fputs("hello world\n", fp);/* Write a piece of information */
    fseek( fp, 6, SEEK_SET );/* The read/write position is moved back 6 positions from the beginning */
    fputs("xxpcb.github.io\n", fp);/* Write another piece of information */
    if(0! =fputs("Code farmers love to learn \n", fp));/* Write another piece of information */
    {
    	printf("fputs file ok\r\n");
	}

    
    / * closed * /
    fclose(fp);
    
    /* open */
    fp = fopen(".. /test-futs.txt"."rt");
    if(NULL == fp)
    {
        printf("open file fail\r\n");
        goto end;
    }
    
    / * * /
    printf("fgets file ... \r\n");
    char str[N+1];
    int line = 0; 
    while(fgets(str, N, fp) ! =NULL)/* Use while to get */ line by line
    {
        printf("[%d]:%s", ++line, str);
    }
    
end:
   return(0);
}
Copy the code

The corresponding design idea of the code is as follows:

Side note: The test code for this and the previous article is available from my Gitee repository (gitee.com/xxpcb/c-tes… ~