Basic concepts of documents
- File stream:
- c language regards a file as a sequence of characters, that is, a file is a character stream composed of one character. Therefore, c language also calls a file a file stream.
- Document classification
-
text file
- It is stored in ASCII format, and one character is stored in one byte. Each byte of the text file stores an ASCII code, representing a character. This facilitates character by character processing, but takes up storage space
More, and it takes time to convert. - . c files are stored as text files
-
Binary file
- Stored in complement format. Binary files store data in files in the form of binary numbers, which takes up less storage space. The data is stored as it is in the memory
- The. exe file is stored as a binary file
- Examples of text and binary files
- The following code is not required to be understood for the time being. It mainly understands what is a text file and what is a binary file
#include <stdio.h>
int main()
{
/*
* Store as text
* Each character will be converted to the corresponding ASCII first,
* Then the binary of ASCII code is stored in the computer
*/
int num = 666;
FILE *fa = fopen("ascii.txt", "w");
fprintf(fa, "%d", num);
fclose(fa);
/*
* Stored in binary form
* The binary of 666 will be stored directly in the file
*/
FILE *fb = fopen("bin.txt", "w");
fwrite(&num, 4, 1, fb);
fclose(fb);
return 0;
}
- By default, the text tool will directly decode the files one by one according to the ASCII code. Because the text file stores the ASCII code, it can be parsed and displayed normally. Because the binary file stores no ASCII code, it is garbled after parsing
Opening and closing of files
- FILE structure
- The FILE structure is the recorder of the read and write status of buffers and files. All operations on files are completed through the FILE structure.
struct _iobuf {
char *_ptr; //Next location for file input
int _cnt; //The relative position of the current buffer
char *_base; //(start of file)
int _flag; //File flag
int _file; //Validation of documents
int _charbuf; //Check the buffer condition. If there is no buffer, it will not be read
int _bufsiz; // Buffer size
char *_tmpfname; //Temporary file name
};
typedef struct _iobuf FILE;
Function declaration | FILE * fopen ( const char * filename, const char * mode ); |
---|
File | stdio.h |
Function function | In mode, open a FILE named filename and return a pointer to the FILE structure of the FILE buffer. |
Parameter and return analysis | |
parameter | char*filaname: the path to open or create the file. |
parameter | char*mode: the way to open a file. |
Return value | FILE * returns a pointer to the FILE buffer, which is the handle of the subsequent operation FILE. |
mode | Treatment method | When the file does not exist | When file exists | Input to file | Export from file |
---|
r | read | error | Open file | No | sure |
w | write in | Create new file | Overwrite original file | sure | No |
a | Add | Create new file | Append after original document | sure | No |
r+ | Read / write | error | Open file | sure | sure |
w+ | Write / read | Create new file | Overwrite original file | sure | sure |
a+ | Read / append | Create new file | Append after original document | sure | sure |
Note:
- If Windows reads and writes binary files, it also needs to add b, such as rb, r+b, etc. unix/linux does not distinguish between text and binary files
Function declaration | int fclose ( FILE * stream ); |
---|
File | stdio.h |
Function function | fclose() is used to close files previously opened by fopen() |
Function function | This action will make the data in the buffer write to the file and release the file resources provided by the system |
Parameter and return analysis | |
parameter | * pointer to the buffered file: stream. |
Return value | int returns 0 for success and EOF(-1) for failure. |
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "w+");
fclose(fp);
return 0;
}
–
Read and write one character at a time
Function declaration | int fputc (int ch, FILE * stream ); |
---|
File | stdio.h |
Function function | Write the ch character to the file. |
Parameter and return analysis | |
parameter | * pointer to the buffered file: stream. |
parameter | int: the character to be written. |
Return value | int is written successfully, and the character of write success is returned. If it fails, EOF is returned. |
#include <stdio.h>
int main()
{
// 1. Open a file
FILE *fp = fopen("test.txt", "w+");
// 2. Write content to the file
for(char ch = 'a'; ch <= 'z'; ch++){
// Write one character at a time
char res = fputc(ch, fp);
printf("res = %c\n", res);
}
// 3. Close the open file
fclose(fp);
return 0;
}
Function declaration | int fgetc ( FILE * stream ); |
---|
File | stdio.h |
Function function | Read a character from the file stream and return it. |
Parameter and return analysis | |
parameter | * pointer to the buffered file: stream. |
Return value | int is normal and returns the read characters; EOF when the end of the file is read or an error occurs. |
#include <stdio.h>
int main()
{
// 1. Open a file
FILE *fp = fopen("test.txt", "r+");
// 2. Read content from file
char res = EOF;
while((res = fgetc(fp)) != EOF){
printf("res = %c\n", res);
}
// 3. Close the open file
fclose(fp);
return 0;
}
- Judge the end of the file
Function declaration | int feof( FILE * stream ); |
---|
File | stdio.h |
Function function | Judge whether the file is read to the end of the file |
Parameter and return analysis | |
parameter | * pointer to the buffered file: stream. |
Return value | int 0 did not read to the end of the file, non-zero read to the end of the file. |
#include <stdio.h>
int main()
{
// 1. Open a file
FILE *fp = fopen("test.txt", "r+");
// 2. Read content from file
char res = EOF;
// Note: since the flag bit can be modified only after reading it first,
// Therefore, to judge whether to reach the end of the file through feof, you must read it first and then judge it. You can't judge it first and then read it
while((res = fgetc(fp)) && (!feof(fp))){
printf("res = %c\n", res);
}
// 3. Close the open file
fclose(fp);
return 0;
}
- Note:
- feof this function is to read the flag bit to determine whether the file is over.
- The flag bit can only be modified after reading, so if you judge first and then read the flag bit, you will hit it again
- Therefore, when using feof function in enterprise development, we must read it first and then judge it, not judge it first and then read it
- task
- Realize the simple encryption and decryption of files
#include <stdio.h>
#include <string.h>
void encode(char *name, char *newName, int code);
void decode(char *name, char *newName, int code);
int main()
{
encode("main.c", "encode.c", 666);
decode("encode.c", "decode.c", 666);
return 0;
}
/**
* @brief encode Encrypted file
* @param name File name to be encrypted
* @param newName Encrypted file name
* @param code Secret key
*/
void encode(char *name, char *newName, int code){
FILE *fw = fopen(newName, "w+");
FILE *fr = fopen(name, "r+");
char ch = EOF;
while((ch = fgetc(fr)) && (!feof(fr))){
fputc(ch ^ code, fw);
}
fclose(fw);
fclose(fr);
}
/**
* @brief encode Decrypt file
* @param name Name of the file to be decrypted
* @param newName Decrypted file name
* @param code Secret key
*/
void decode(char *name, char *newName, int code){
FILE *fw = fopen(newName, "w+");
FILE *fr = fopen(name, "r+");
char ch = EOF;
while((ch = fgetc(fr)) && (!feof(fr))){
fputc(ch ^ code, fw);
}
fclose(fw);
fclose(fr);
}
Read and write one line of characters at a time
- Line is a concept in the text editor, and a character is in the file stream. This is different on different platforms. Windows platform '\ r\n', linux platform '\ r\n'
- Platform differences
- When writing '\ n' on windows platform, it will be reflected as' \ r\n ', and when writing' \ n 'on linux platform, it will be reflected as' \ n'. When reading '\ r\n' in windows platform, it is reflected as a character '\ n', and when reading '\ n' in linux platform, it is reflected as a character '\ n'
- If linux reads the line feed in windows, it will read one more character. If windows reads the line feed in linux, there is no problem
#include <stdio.h>
int main()
{
FILE *fw = fopen("test.txt", "w+");
fputc('a', fw);
fputc('\n', fw);
fputc('b', fw);
fclose(fw);
return 0;
}
Function declaration | int fputs(char *str,FILE *fp) |
---|
File | stdio.h |
Function function | Write the string pointed to by str to the file pointed to by fp. |
Parameter and return analysis | |
parameter | char * str: pointer to the string pointed to. |
parameter | FILE *fp: pointer to the file stream structure. |
Return value | int normal, return to 0; Error returned to EOF. |
#include <stdio.h>
int main()
{
FILE *fw = fopen("test.txt", "w+");
// Note: fputs will not be automatically added \ n
fputs("lnj\n", fw);
fputs("it666\n", fw);
fclose(fw);
return 0;
}
- Encountered \ 0 auto terminate write
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "w+");
// Note: fputs will automatically terminate writing when encountering \ 0 during writing
fputs("lnj\0it666\n", fp);
fclose(fp);
return 0;
}
Function declaration | char *fgets(char *str,int length,FILE *fp) |
---|
File | stdio.h |
Function function | Read at most length-1 characters from the file pointed to by fp and send them into the character array str. if you encounter \ n or EOF before the end of reading length-1 characters, the reading will end. After reading the string, add a '\ 0' character at the end. |
Parameter and return analysis | |
parameter | char * str: point to the buffer where data needs to be read in. |
parameter | int length: the number of characters read at each time. |
parameter | FILE* fp: file stream pointer. |
Return value | char * normal, return str pointer; Error or NULL pointer returned at end of file encountered. |
- A maximum of N-1 characters can be read
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "w+");
// Note: fputs will not be automatically added \ n
fputs("it666\n", fp);
// Move the read-write pointer in the FILE structure back to the front
// Note: the read / write pointer in the FILE structure will move back after each character is read or written
rewind(fp);
char str[1024];
// Read 4 characters from fp and store them in str
// Can only read N-1 characters at most, and will be automatically added at the end \ 0
fgets(str, 4, fp);
printf("str = %s", str); // it6
fclose(fp);
return 0;
}
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "w+");
// Note: fputs will not be automatically added \ n
fputs("lnj\n", fp);
fputs("it666\n", fp);
// Move the read-write pointer in the FILE structure back to the front
// Note: the read / write pointer in the FILE structure will move back after each character is read or written
rewind(fp);
char str[1024];
// Read 1024 characters from fp and store them in str
// But after reading the fourth one, the function will automatically stop reading
// Note: \ n will be read in
fgets(str, 1024, fp);
printf("str = %s", str); // lnj
fclose(fp);
return 0;
}
- Read EOF automatically ends
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "w+");
// Note: fputs will not be automatically added \ n
fputs("lnj\n", fp);
fputs("it666", fp);
// Move the read-write pointer in the FILE structure back to the front
// Note: the read / write pointer in the FILE structure will move back after each character is read or written
rewind(fp);
char str[1024];
// 1024 characters are read from fp each time and stored in str
// Automatic end when reading to the end of the file
while(fgets(str, 1024, fp)){
printf("str = %s", str);
}
fclose(fp);
return 0;
}
- Note:
- feof function is not needed in enterprise development
- If there is no line '\ n' in the last line, read one less line
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "w+");
// Note: fputs will not be automatically added \ n
fputs("12345678910\n", fp);
fputs("12345678910\n", fp);
fputs("12345678910", fp);
// Move the read-write pointer in the FILE structure back to the front
// Note: the read / write pointer in the FILE structure will move back after each character is read or written
rewind(fp);
char str[1024];
// 1024 characters are read from fp each time and stored in str
// Automatic end when reading to the end of the file
while(fgets(str, 1024, fp) && !feof(fp)){
printf("str = %s", str);
}
fclose(fp);
return 0;
}
- Job:
- How many times will the following text be read using fgets(str, 5, fp)?
12345678910
12345
123
Read and write one piece of data at a time
- C language has been distinguished from the interface level, text reading and writing mode and binary reading and writing mode. What we talked about earlier is the way of reading and writing text.
- All file interface functions either end with '\ 0', or end with '\ n', EOF(0xFF)\ 0 '' \ n 'and others are important identifications of text files, and all binary interfaces are insensitive to these identifications.
+Binary interfaces can read text, while text interfaces cannot read binary
- Write one piece of data at a time
Function declaration | int fwrite(void *buffer, int num_bytes, int count, FILE *fp) |
---|
File | stdio.h |
Function function | Write the data pointed to by buffer into the file pointed to by fp |
parameter | char * buffer: pointer to the first address of the data storage area to be written |
| int num_bytes: bytes of each field to be written count |
| int count: the number of fields to write |
| FILE* fp: pointer to the file to be written |
Return value | int success, return the number of fields written; Error or end of file, return 0. |
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp = fopen("test.txt", "wb+");
// Note: fwrite does not care about the format of the written data
char *str = "lnj\0it666";
/*
* First parameter: written data pointer
* Second parameter: how many bytes are written each time
* The third parameter: how many times to write
* Fourth parameter: pointer to the opened file structure
*/
fwrite((void *)str, 9, 1, fp);
fclose(fp);
return 0;
}
- Read one piece of data at a time
Function declaration | int fread(void *buffer, int num_bytes, int count, FILE *fp) |
---|
File | stdio.h |
Function function | Read the data in the file pointed to by fp into the buffer. |
parameter | char * buffer: pointer to the first address of the data storage area to be read |
| int num_bytes: bytes of each field to be read count |
| int count: the number of fields to read |
| FILE* fp: pointer to the file to be read |
Return value | int success, return the number of read fields; Error or end of file, return 0. |
#include <stdio.h>
int main()
{
// test.txt is "lnj"lnj \ 0it666"it666"
FILE *fr = fopen("test.txt", "rb+");
char buf[1024] = {0};
// The fread function returns the number of bytes read after reading successfully, and 0 if reading fails
/*
* First parameter: the container that stores the read data
* Second parameter: how many bytes are read each time
* The third parameter: how many times to read
* Fourth parameter: pointer to the opened file structure
*/
int n = fread(buf, 1, 1024, fr);
printf("%i\n", n);
for(int i = 0; i < n; i++){
printf("%c", buf[i]);
}
fclose(fr);
return 0;
}
- Note:
- Read num_bytes should be filled in the minimum unit of the read data type, while count can be written at will
- If num is read_ Bytes is not the smallest unit of read data type, which will cause read failure
- For example, stored is char type 6C 6e 6A 00 69 74 36
If num_ If bytes is equal to 1 and count is equal to 1024, take out 6C 6e 6A 00 69 74 36 successively until it cannot be taken
If num_ If bytes is equal to 4 and count is equal to 1024, then [6C 6E 6A 00][69 74 36 36] will be taken out in turn, but there is still one 36 left, but it does not meet 4 bytes, then the last 36 will not be taken
#include <stdio.h>
#include <string.h>
int main()
{
// test.txt is "lnj"lnj \ 0it666"it666"
FILE *fr = fopen("test.txt", "rb+");
char buf[1024] = {0};
/*
while(fread(buf, 4, 1, fr) > 0){
printf("%c\n", buf[0]);
printf("%c\n", buf[1]);
printf("%c\n", buf[2]);
printf("%c\n", buf[3]);
}
*/
/*
while(fread(buf, 1, 4, fr) > 0){
printf("%c\n", buf[0]);
printf("%c\n", buf[1]);
printf("%c\n", buf[2]);
printf("%c\n", buf[3]);
}
*/
while(fread(buf, 1, 1, fr) > 0){
printf("%c\n", buf[0]);
}
fclose(fr);
return 0;
}
- Note: fwrite and fread are essentially used to manipulate binaries
- So the following usage is their correct opening posture
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "wb+");
int ages[4] = {1, 3, 5, 6};
fwrite(ages, sizeof(ages), 1, fp);
rewind(fp);
int data;
while(fread(&data, sizeof(int), 1, fp) > 0){
printf("data = %i\n", data);
}
return 0;
}
Read write structure
- The data types in the structure are not unified. At this time, it is most suitable to read and write in binary mode
- Read and write single structure
#include <stdio.h>
typedef struct{
char *name;
int age;
double height;
} Person;
int main()
{
Person p1 = {"lnj", 35, 1.88};
// printf("name = %s\n", p1.name);
// printf("age = %i\n", p1.age);
// printf("height = %lf\n", p1.height);
FILE *fp = fopen("person.stu", "wb+");
fwrite(&p1, sizeof(p1), 1, fp);
rewind(fp);
Person p2;
fread(&p2, sizeof(p2), 1, fp);
printf("name = %s\n", p2.name);
printf("age = %i\n", p2.age);
printf("height = %lf\n", p2.height);
return 0;
}
- Read / write structure array
#include <stdio.h>
typedef struct{
char *name;
int age;
double height;
} Person;
int main()
{
Person ps[] = {
{"zs", 18, 1.65},
{"ls", 21, 1.88},
{"ww", 33, 1.9}
};
FILE *fp = fopen("person.stu", "wb+");
fwrite(&ps, sizeof(ps), 1, fp);
rewind(fp);
Person p;
while(fread(&p, sizeof(p), 1, fp) > 0){
printf("name = %s\n", p.name);
printf("age = %i\n", p.age);
printf("height = %lf\n", p.height);
}
return 0;
}
- Read write structure linked list
#include <stdio.h>
#include <stdlib.h>
typedef struct person{
char *name;
int age;
double height;
struct person* next;
} Person;
Person *createEmpty();
void insertNode(Person *head, char *name, int age, double height);
void printfList(Person *head);
int saveList(Person *head, char *name);
Person *loadList(char *name);
int main()
{
// Person *head = createEmpty();
// insertNode(head, "zs", 18, 1.9);
// insertNode(head, "ls", 22, 1.65);
// insertNode(head, "ws", 31, 1.78);
// printfList(head);
// saveList(head, "person.list");
Person *head = loadList("person.list");
printfList(head);
return 0;
}
/**
* @brief loadList Load linked list from file
* @param name File name
* @return Loaded chain header pointer
*/
Person *loadList(char *name){
// 1. Open the file
FILE *fp = fopen(name, "rb+");
if(fp == NULL){
return NULL;
}
// 2. Create an empty linked list
Person *head = createEmpty();
// 3. Create a node
Person *node = (Person *)malloc(sizeof(Person));
while(fread(node, sizeof(Person), 1, fp) > 0){
// 3. Insert
// 3.1 make the next node of the new node equal to the next node of the head node
node->next = head->next;
// 3.2 make the next node of the head node equal to the new node
head->next = node;
// Apply for space for the next node
node = (Person *)malloc(sizeof(Person));
}
// Free up extra node space
free(node);
fclose(fp);
return head;
}
/**
* @brief saveList Store linked list to file
* @param head Chain header pointer
* @param name Stored file name
* @return Store success - 1 failed 0 succeeded
*/
int saveList(Person *head, char *name){
// 1. Open the file
FILE *fp = fopen(name, "wb+");
if(fp == NULL){
return -1;
}
// 2. Take out the next node of the head node
Person *cur = head->next;
// 3. Save all valid nodes to a file
while(cur != NULL){
fwrite(cur, sizeof(Person), 1, fp);
cur = cur->next;
}
fclose(fp);
return 0;
}
/**
* @brief printfList Traversal linked list
* @param head Head pointer of linked list
*/
void printfList(Person *head){
// 1. Take out the next node of the head node
Person *cur = head->next;
// 2. Judge whether it is NULL. If it is not NULL, start traversal
while(cur != NULL){
// 2.1 take out the data of the current node and print it
printf("name = %s\n", cur->name);
printf("age = %i\n", cur->age);
printf("height = %lf\n", cur->height);
printf("next = %x\n", cur->next);
printf("-----------\n");
// 2.2 move the current node backward
cur = cur->next;
}
}
/**
* @brief insertNode Insert new node
* @param head Head pointer of linked list
* @param p Structure to be inserted
*/
void insertNode(Person *head, char *name, int age, double height){
// 1. Create a new node
Person *node = (Person *)malloc(sizeof(Person));
// 2. Save data to a new node
node->name = name;
node->age = age;
node->height = height;
// 3. Insert
// 3.1 make the next node of the new node equal to the next node of the head node
node->next = head->next;
// 3.2 make the next node of the head node equal to the new node
head->next = node;
}
/**
* @brief createEmpty Create an empty linked list
* @return Chain header pointer, NULL returned if creation failed
*/
Person *createEmpty(){
// 1. Define header pointer
Person *head = NULL;
// 2. Create a null node and assign it to the header pointer
head = (Person *)malloc(sizeof(Person));
if(head == NULL){
return head;
}
head->next = NULL;
// 3. Return header pointer
return head;
}
Other file operation functions
Function declaration | long ftell ( FILE * stream ); |
---|
File | stdio.h |
Function function | Get the current read / write position of the streaming file, and its return value is the number of bytes that the current read / write position deviates from the file header |
Parameter and return analysis | |
parameter | FILE * stream FILE handle |
Return value | int succeeded. Returns the number of bytes that the current read / write position deviates from the file header. Failed, return - 1 |
#include <stdio.h>
int main()
{
char *str = "123456789";
FILE *fp = fopen("test.txt", "w+");
long cp = ftell(fp);
printf("cp = %li\n", cp); // 0
// Write a byte
fputc(str[0], fp);
cp = ftell(fp);
printf("cp = %li\n", cp); // 1
fclose(fp);
return 0;
}
Function declaration | void rewind ( FILE * stream ); |
---|
File | stdio.h |
The function redirects the file pointer to the beginning of a stream. | |
Parameter and return analysis | |
parameter | FILE * stream FILE handle |
Return value | void has no return value |
#include <stdio.h>
int main()
{
char *str = "123456789";
FILE *fp = fopen("test.txt", "w+");
long cp = ftell(fp);
printf("cp = %li\n", cp); // 0
// Write a byte
fputc(str[0], fp);
cp = ftell(fp);
printf("cp = %li\n", cp); // 1
// New points to the beginning of a stream
rewind(fp);
cp = ftell(fp);
printf("cp = %li\n", cp); // 0
fclose(fp);
return 0;
}
Function declaration | int fseek ( FILE * stream, long offset, int where); |
---|
File | stdio.h |
Function function | Offset file pointer. |
Parameter and return analysis | |
Parameters | FILE * stream file handle |
| long offset offset |
| int where offset start position |
Return value | int returns 0 for success and - 1 for failure |
#define SEEK_CUR 1 current text
#define SEEK_END 2 end of file
#define SEEK_ Start of set 0 file
#include <stdio.h>
int main()
{
FILE *fp = fopen("test.txt", "w+");
fputs("123456789", fp);
// Move the file pointer to the end of the file and offset by 0 units
fseek(fp, 0, SEEK_END);
int len = ftell(fp); // Calculate file length
printf("len = %i\n", len);
fclose(fp);
return 0;
}
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("file.txt","w+");
fputs("123456789", fp);
fseek( fp, 7, SEEK_SET );
fputs("lnj", fp);
fclose(fp);
return 0;
}
If you think the article is helpful to you, click like, collect, pay attention to and comment, and support four times with one button, your support is the driving force for brother Jiang's continuous update