Table of contents
1. Classification by storage medium
2. Classified by storage method
Fourth, the difference between binary and file files
1. How to refresh the file buffer
3. Read and write fgetc fputc character by character
4. Read and write a string at a time fgets fputs
5. Read and write n blocks of file data at a time fread fwrite
6. Formatting read and write fscanf fprintfEdit
1. Format and write fprintf (file pointer, format string, output list)
2. Formatted read fscanf (file pointer, format string, output list)
7. Random reading and writing of files
1. Sequential reading and writing introduces random reading and writing cases
(1) rewind resets the file stream pointer
(2) ftell returns the number of bytes from the file stream pointer to the file header
(3) fseek file stream pointer positioning
1. File classification
1. Classification by storage medium
Disk file: the data of the file is stored on the disk (audio and video, picture files, document files)
Device file: abstract the external device file through the system
2. Classified by storage method
Physically : Any disk file is physically a binary storage.
Logically : Disk files are divided into binary files and text files .
2. Text file
Text files are based on character encoding, common encodings include ASCII , UNICODE, etc. Generally, you can directly open it with a text editor
For example:
(1) The number 5678 is stored in ASCII as ASCII code:
00110101(==53=='5') 00110110 00110111 00111000 4B in total
(2) Lyric file (lrc): text file
3. Binary code file
Based on value encoding, the data in the memory is output to the disk as it is . Generally, you need to judge by yourself or use specific software to analyze the data format .
For example: the storage form of the number 5678 is: Binary code: 00010110 00101110
Fourth, the difference between binary and file files
Text file:
Advantages: One byte represents one meaning, easy to view
Disadvantages: large space, low efficiency
binary file:
Advantages: high efficiency, small space
Disadvantages: variable length, inconvenient to view
Five, the file buffer
1. How to refresh the file buffer
1. Line refresh: Refresh when a newline character is encountered .
2. Full refresh: the buffer data is full and refreshed
3. Forced refresh Use the fflush function to refresh the buffer
4. Turn off play new: when the program finishes running, all the buffer data will be refreshed
2. Analog clock
#include<unistd.h>
void test()
{
int i=0;
while(1)
{
printf(\r%02d:%02d",i/60,i%60);//\r回到行首
fflush(stdout);//强制刷新
sleep(1);
i++;
}
3. File pointer
All library functions that operate files need to use file pointers to operate files .
3 file pointers opened by default for each process:
(1) stdin : The standard input is the current terminal (keyboard) by default.
The scanf and getchar functions we use get data from this terminal by default.(2) stdout : standard output , the default is the current terminal (screen)
The printf and puts functions we use output information to this terminal by default
(3) stderr : the standard error output device file defaults to the current terminal (screen)When our program makes an error and uses the: perror function, the information is printed on this terminal
例:fgets(buf,sizeof(buf),stdin);
fwrite("hello world",12,1,stdout);//12 blocks of 1 byte output
6. File API
File operation steps: open, read, write, close
1. Open the file fopen
f in fopen describes it as a library function, and its bottom layer uses the open function to complete the system call.
Definition: FILE *fopen(const char *path, const char *mode);
path: the path of the file
mode: Open file mode
return value:
Success: the open file pointer
Failed: NULL
File opening mode: r, w, a, +, t, b
r : open as read-only
w : Open for writing only
a : Open by appending (clear and rewrite)
+ : open in readable and writable mode
t : Open as a text file (default, can be omitted)
b : open in binary mode (must show description)
Combination method:
model | Function |
r or rb | open a file read-only (do not create a file) |
w or wb | Open file for writing (truncate file length to 0 bytes ( delete ), create a file) |
a or ab | Open the file in the append mode, that is, add content at the end. When the file does not exist, create a file for append writing |
r+ or rb+ | Open the file for reading and writing ( do not create a new file) |
w+ or wb+ | Open file as readable, writable (make file length 0 bytes ( delete ), create a file) |
a+ or ab+ | Open the file as add, open the file and change the file at the end (create the file if it doesn't exist) |
2. Close the file fclose
Definition: int fclose(FILE *fp);
return value:
Returns 0 on success
Return non-0 on failure
void test()
{
FILE* fp = NULL;
fp = fopen("test.txt", "r");
if (fp = NULL)//文件不存在
{
perror("fopen");
return;
}
fclose(fp);
}
3. Read and write fgetc fputc character by character
Write one byte at a time : fputc
Function definition: int fputc(int c, FILE *stream)
Function description: fputc writes the value of c to the file represented by stream.
Return value:
If the output is successful , return the byte value of the output ;Returns an EOF if output fails .
EOF is a macro symbol constant defined in the stdio.h file, with a value of -1, and EOF is only valid in text files .
Write the hello world string:
void test()
{
FILE* fp = NULL;
fp = fopen("test.txt", "w");
if (fp = NULL)
{
perror("fopen");
return;
}
char* file_data = "hello word";
while (*file_data != '\0')
{
fputc(*file_data, fp);
file_data++;
}
fclose(fp);
}
Read one byte at a time : fgetc
Function definition: int fgetc(FILE *stream);
Function description: fgetc reads a byte from the file marked by stream, and returns the byte value
Return value:
in the way of t : read to the end of the file and return EOF
in the way of b : read to the end of the file, use the feof function (will be discussed later) to judge the end
Read strings one by one:
void test()
{
FILE* fp = NULL;
fp = fopen("test.txt", "r");
if (fp = NULL)
{
perror("fopen");
return;
}
while(1)
{
char ch = fgetc(fp);
if (ch != EOF)
break;
printf("%c", ch);
}
fclose(fp);
}
4. Read and write a string at a time fgets fputs
Write a string: int fputs(const char *s, FILE *stream)
Read a string: char *fgets(char *s, int size, FILE *stream)
Read a string (end of line break), read a line of file data
Successfully return the first address of the destination array , namely s
Return NULL on failure
There is a test program that reads the data in the test.txt file and writes it to b.txt under the test.txt file:
void test06()
{
FILE *fp_r = fopen("test.txt", "r");
if (fp_r == NULL)
{
perror("fopen");
return;
}
FILE *fp_w = fopen("b.txt", "w");
if (fp_w == NULL)
{
perror("fopen");
return;
}
while (1)
{
char buf[128] = "";//存放读到的数据并写到b.txt中
//读一行
char *ret = fgets(buf, sizeof(buf), fp_r);
if (ret == NULL)
break;
//写一行
fputs(buf, fp_w);
}
fclose(fp_r);
fclose(fp_w);
}
5. Read and write n blocks of file data at a time fread fwrite
块写:size_t fwrite(void *ptr, size_t size, size_t n, FILE *stream);
Function description: The fwrite function writes the data in the memory pointed to by ptr to the file marked by stream, one block is size bytes, and there are n blocks in total.
Block write : Write the data in the memory to the disk file as it is
Return value : the number of blocks actually written
Quick write example:
#include <string.h>
typedef struct
{
int num;
char name[30];
}STU;
void test()
{
STU A[3]={
{1,"lucy"},{2,"bob"},{3,"张三",{4,"李四"}};
int n = sizeof(hero) / sizeof(hero[0]);
FILE *fp = fopen("S.txt", "w");
if (fp == NULL)
{
perror("fopen");
return;
}
fwrite(A, sizeof(A), n, fp);
fclose(fp);
}
快读:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
Quick read : the disk data is input to the memory as it is
Return value: The number of whole blocks actually read : less than one block is not counted but the data is read.
Block read instance
#include <string.h>
void test02()
{
STU A[3];
memset(A, 0, sizeof(A));
FILE *fp = fopen("S.txt", "r");
if (fp == NULL)
{
perror("fopen");
return;
}
fread(A, sizeof(STU), 3, fp);
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%d %s\n", A[i].num, A[i].name);
}
fclose(fp);
}
6. Formatting read and write fscanf fprintf
1. Format and write fprintf (file pointer, format string, output list)
#include <string.h>
typedef struct
{
int num;
char name[30];
}STU;
void test()
{
STU A[3]={
{1,"lucy"},{2,"bob"},{3,"张三",{4,"李四"}};
int n = sizeof(hero) / sizeof(hero[0]);
FILE *fp = fopen("S.txt", "w");
if (fp == NULL)
{
perror("fopen");
return;
}
//格式化写
int i = 0;
for (i = 0; i < n; i++)
{
fprintf(fp, "%s %d \n", A[i].num, A[i].name);
}
fclose(fp);
}
2. Formatted read fscanf (file pointer, format string, output list)
#include <string.h>
void test02()
{
STU A[3];
memset(A, 0, sizeof(A));
FILE *fp = fopen("S.txt", "r");
if (fp == NULL)
{
perror("fopen");
return;
}
int i = 0;
for (i = 0; i < 3; i++)
{
fscanf(fp, "%d %s",&A[i].num, A[i].name);
}
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%d %s\n", A[i].num, A[i].name);
}
fclose(fp);
}
7. Random reading and writing of files
By default, the file is read and written in the order of stream pointers , and the user cannot change the order of reading and writing by moving the stream pointers .
Random read and write: users can change the position of the file stream pointer
1. Sequential reading and writing introduces random reading and writing cases
void test()
{
FILE* fp = NULL;
fp = fopen("test.txt", "w+");
if (fp = NULL)
{
perror("fopen");
return;
}
fpus("hello world", fp);//此时流指针指向该字符串末尾
char buf[100] = "";
//读时从流指针开始往后顺序读,会读不到字符串hello world
fgets(buf, sizeof(buf), fp);
printf("读到的数据:%s\n", buf);//无数据显示
fclose(fp);
}
Sequential reading and writing solves this problem: the stream pointer will be reset after the file is closed and reopened. But the file is opened twice and closed twice.
void test()
{
FILE* fp = NULL;
fp = fopen("test.txt", "w+");
if (fp = NULL)
{
perror("fopen");
return;
}
fpus("hello world", fp);//此时流指针指向该字符串末尾
//流指针复位
fclose(fp);
fp=fopen("test.txt","r");
//读取数据
char buf[100] = "";
fgets(buf, sizeof(buf), fp);
printf("读到的数据:%s\n", buf);
fclose(fp);
}
2. Random read and write API
(1) rewind resets the file stream pointer
void rewind(FILE *stream);
void test()
{
FILE* fp = NULL;
fp = fopen("test.txt", "w+");
if (fp = NULL)
{
perror("fopen");
return;
}
fpus("hello world", fp);//此时流指针指向该字符串末尾
//复位文件流指针
rewind(fp);
//读取数据
char buf[100] = "";
fgets(buf, sizeof(buf), fp);
printf("读到的数据:%s\n", buf);
fclose(fp);
}
(2) ftell returns the number of bytes from the file stream pointer to the file header
long ftell(FILE *stream);
void test()
{
FILE* fp = NULL;
fp = fopen("test.txt", "w+");
if (fp = NULL)
{
perror("fopen");
return;
}
fpus("hello world", fp);//此时流指针指向该字符串末尾
//复位文件流指针
long len=ftell(fp);
printf("文件的大小:%ld\n", len);
fclose(fp);
}
(3) fseek file stream pointer positioning
int fseek(FILE *stream, long offset, int whence);
whence locates the starting position of the stream pointer
File starts with SEEK_SET 0
File current position SEEK_ CUR 1
end of file SEEK_ END 2
offset: the offset of the stream pointer , if it is a positive number, the offset to the right (in bytes) is a negative number, it is an offset to the left
Case: Read file data at one time
The main steps:
(1) Position the file stream pointer to the end
(2) ftell returns the offset of the file stream pointer (total file size len)
(3) According to the total file size, apply for space len+1 from the heap area
(4) Use fread to read the file data at one time
Implementation code:
#include <stdlib.h>
#include <string.h>
void test06()
{
FILE *fp = fopen("c.txt", "r");
if (fp == NULL)
{
perror("fopen");
return;
}
fseek(fp, 0, 2);
long len = ftell(fp);
//复位文件流指针
rewind(fp);
printf("文件总大小:len=%ld\n", len);
unsigned char *text = (unsigned char *)calloc(1, len + 1);
fread(text, len, 1, fp);
printf("%s\n", text);
fclose(fp);
//释放堆区空间(不是必须操作)
if (text != NULL)
{
free(text);
text = NULL;
}
}
8. File Encryptor
main.c
#include <stdio.h>
#include <stdlib.h>
#include "fun.h"
int main(int argc ,char *argv[])
{
while(1)
{
int cmd=0;
print_help();
printf("请输入指令:");
scanf("%d",&cmd);
if(cmd==1)
{
char dest_file[31]="";
char src_file[31]="";
unsigned long file_length=0;
char *read=NULL;
unsigned int password=0;
//从键盘获取源文件和目的文件名字
get_file_name(dest_file,src_file);
//从文件中读出内容
read = read_src_file(&file_length,src_file);
//获取加密password
printf("请输入密码:");
scanf("%u",&password);
//字符数组加密
read=file_text_encrypt(read,file_length,password);
//保存文件
save_file(read,file_length,dest_file);
}
else if (cmd==2)
{
char dest_file[31]="";
char src_file[31]="";
unsigned long file_length=0;
char *read=NULL;
unsigned int password=0;
//从键盘获取源文件和目的文件名字
get_file_name(dest_file,src_file);
//从文件中读出内容
read = read_src_file(&file_length,src_file);
//获取加密password
printf("请输入密码:");
scanf("%u",&password);
//字符数组加密
read=file_text_decrypt(read,file_length,password);
//保存文件
save_file(read,file_length,dest_file);
}
else if (cmd==3)
{
break;
}
else
{
printf("输入指令出错!!!\n");
}
}
return 0;
}
fun.c
#include <stdio.h>
#include <stdlib.h>
void print_help()
{
printf("********1:加密文件***********\n");
printf("********2:解密文件***********\n");
printf("********3:退出程序***********\n");
}
void get_file_name(char * dest_file_name,char * src_file_name)
{
printf("请输入源文件的名称:");
scanf("%s",src_file_name);
printf("请输入目的文件的名称:");
scanf("%s",dest_file_name);
return;
}
char *read_src_file(unsigned long *file_length,char *src_file_name)
{
char *data=NULL;
FILE *fp;
fp=fopen(src_file_name,"r");//只读的方式打开文件
if(fp==NULL)
{
perror("fopen");
return NULL;
}
//流指针go尾部
fseek(fp,0,2);
//流指针的偏移量
*file_length = ftell(fp);
//流指针复位
rewind(fp);
//申请空间保存文件
data=(char *)calloc(1,*file_length);
if(NULL==data)
{
perror("calloc");
return NULL;
}
//一次性读
fread(data,*file_length,1,fp);
fclose(fp);
return data;
}
char *file_text_encrypt(char * src_file_text,unsigned long int length,unsigned int password)
{
char *data=NULL;
unsigned int i=0;
for(i=0;i<length;i++)
{
src_file_text[i] += password;
}
return src_file_text;
}
void save_file(char* text,unsigned long int length,char * file_name)
{
char *data=NULL;
FILE *fp;
fp=fopen(file_name,"w");
if(NULL==fp)
{
perror("fp");
return;
}
//写
fwrite(text,length,1,fp);
fclose(fp);
if(text !=NULL)
{
free(text);
text =NULL;
}
return;
}
char *file_text_decrypt(char * src_file_text,unsigned long int length,unsigned int password)
{
char *data=NULL;
unsigned int i=0;
for(i=0;i<length;i++)
{
src_file_text[i] -= password;
}
return src_file_text;
}
fun.h
#ifndef __FUN_H__
#define __FUN_H__
extern void print_help();
extern void get_file_name(char * dest_file_name,char * src_file_name);
extern char *read_src_file(unsigned long *file_length,char *src_file_name);
extern char *file_text_encrypt(char * src_file_text,unsigned long int length,unsigned int password);
extern void save_file(char* text,unsigned long int length,char * file_name);
extern char *file_text_decrypt(char * src_file_text,unsigned long int length,unsigned int password);
#endif