The file opening operation has been discussed before. The following describes the file read and write operations. There are four types of file read/write operations: character read/write, string read/write, block read/write, and formatted read/write.
I. Read and Write characters
Character reading and writing mainly uses two functions: fputc and fgetc. The prototype of the two functions is:
Int fputc (int ch, FILE * fp); If the write is successful, the written characters are returned; otherwise,-1 is returned.
Int fgetc (FILE * fp); If the read is successful, the read character is returned; otherwise,-1 is returned.
Note: 1) For fputc and fgetc functions, fputc can only write 1 byte of data at each operation, regardless of the ch parameter, only the low 8-bit data is written into the file; fgetc can return only one byte of data at a time.
2) For the fgetc function, if the read is successful, the read characters are returned; otherwise,-1 is returned. there are two situations in which-1 (EOF) is returned: one is that there are no characters available for reading at the end of the file, and the other is that there is an error in reading. Generally, explicit characters in a text file cannot contain characters with ASCII code-1, therefore, you can use the returned results of fgetc to determine whether the file is complete (read without errors ). However, this cannot be determined in binary files, because binary files may contain data such as FF. If the variable ch that stores the fgetc read results is defined as char, however, if it is defined as int type, it can also be determined that, even if the read character is FF, but because ch is int type, in fact, ch = 0x000000FF is not equal to-1. Therefore, you can determine whether the file ends. (Note that the above statement is true only when the file is read without errors. If the file is read incorrectly, it cannot be used to determine whether the file is finished. You must use the feof () function to determine whether the file is finished)
Test procedure:
# Include <stdio. h> # include <stdlib. h> int main (void) {FILE * fp; int ch; if (fp = fopen ("test.txt", "wb +") = NULL) {printf ("can not open file \ n"); exit (0);} fputc (-1, fp); // The binary of-1 is FF fputc (385, fp); // 385 binary is 110000001 rewind (fp); ch = fgetc (fp); while (feof (fp) = 0) {printf ("% d \ n", ch); ch = fgetc (fp);} fclose (fp); return 0 ;}
The execution result is:
255
129
Press any key to continue
Since fputc only writes one byte of data at a time, although you want to write 385 for the second time, but only write its low 8-bit data, the output result is 129.
If ch in the above program is defined as char, the execution result is:
-1
-127
Press any key to continue
The reason has been explained above.
Ii. String read/write
String read/write mainly involves two functions: fputs and fgets. The prototype of these two functions is:
Int fputs (const char * s, FILE * fp );
Char * fgets (char * s, int n, FILE * fp );
For the fputs function, the string is written to the file. If the write is successful, a non-negative value is returned; otherwise,-1 is returned;
For the fgets function, no more than n-1 characters are read from the file to the character array (if there are fewer than n-1 characters in the file, only the characters in the file are read ), the system automatically adds '\ 0' at the end of the character array to return the first address of the character array.
Note: 1) for the fgets function, if the character '\ n' is read during the read process, the read process ends ahead of schedule.
Test procedure:
#include<stdio.h>#include<stdlib.h>int main(void){ FILE *fp; char s[10]; if((fp=fopen("test.txt","wb+"))==NULL) { printf("can not open file\n"); exit(0); } fputc('A',fp); fputc('B',fp); fputc('\n',fp); fputc('C',fp); rewind(fp); fgets(s,5,fp); printf("%s\n",s); fclose(fp); return 0;}
The execution result is:
AB
Press any key to continue
It can be seen that the reading stops when the linefeed '\ n' is read.
Iii. Block read/write
Block read/write mainly involves two functions: fread and fwrite. The prototype of these two functions is:
Unsigned int fread (void * buffer, unsigned int size, unsigned int n, FILE * fp );
A group of data read from a file is stored in the memory space with the first address buffer. size is the size of a data block, and n is the number of data blocks to be read. If the data is read successfully, returns the number of data blocks read. Otherwise, 0 is returned.
Unsigned int fwrite (const void * buffer, unsigned int size, unsigned int n, FILE * fp );
Write Data to the file. If the write succeeds, the number of data blocks to be written is returned. Otherwise, 0 is returned.
Block read/write is generally used for struct.
Note: 1) block read/write is often used in struct.
2) fread and fwrite are usually paired. If fwrite is used for file write operations, fread is used for reading. Otherwise, unexpected results may be obtained.
Test procedure:
# Include <stdio. h> # include <stdlib. h> typedef struct node {char name [20]; double score; int age;} Student; int main (void) {FILE * fp; int I; student s1 [3] = {"liudehua", 85.5, 45 },{ "zhangxueyou", 79.3, 47 },{ "guofucheng", 83.4, 43 }}; student s2 [3]; if (fp = fopen ("test.txt", "wb +") = NULL) {printf ("can not open file \ n "); exit (0);} printf ("% d \ n", fwrite (s1, sizeof (Student), 3, fp )); // printf ("% d \ n", fwrite (s1, sizeof (s1), 1, fp); // note the difference between rewind (fp) and the previous sentence ); printf ("% d \ n", fread (s2, sizeof (Student), 3, fp); for (I = 0; I <3; I ++) {printf ("% s % lf % d \ n", s2 [I]. name, s2 [I]. score, s2 [I]. age) ;}fclose (fp); return 0 ;}
The execution result is:
3
3
Liudehua 85.500000 45
Zhangxueyou 79.300000 47
Guofucheng 83.400000 43
Press any key to continue
Iv. formatted read/write
Formatting and reading mainly involve two functions: fscanf and fprintf. The prototype of the two functions is
Int fscanf (FILE * fp, const char * format [, argument]...);
Used to format and read data from a file. If the read is successful, the number of data read is returned. Otherwise,-1 is returned.
Int fprintf (FILE * fp, const char * format [, argument]...);
Used to format and write data to a file. If the write is successful, the number of written characters is returned. Otherwise,-1 is returned.
Note: 1) formatting and reading are very different from other types of reading and writing. Formatted reads and writes data to a file in a format that we can recognize. That is, if we write an integer value 65 in formatting mode, the two characters '6' and '5' are actually written ', that is, it occupies 2 bytes, not 4 bytes, but if it is written in block write mode, it occupies 4 bytes. That is, when formatted read/write is used, the system automatically performs some conversions.
2) fprintf and fscanf functions are usually paired. If the data is written using fprintf, it is best to use fscanf for reading.
3) when writing data using the fprintf function, if the file is opened in text mode, if the parameter format contains '\ n', the final file will be written with a line break; if the file is opened in binary mode, the file will not be written with line breaks. The difference is mentioned in the previous blog.
Test procedure:
#include<stdio.h>#include<stdlib.h>typedef struct node{ char name[20]; double score; int age;}Student;int main(void){ FILE *fp; int i; Student s1[3]={{"liudehua",85.5,45},{"zhangxueyou",79.3,47},{"guofucheng",83.4,43}}; Student s2[3]; if((fp=fopen("test.txt","wb+"))==NULL) { printf("can not open file\n"); exit(0); } for(i=0;i<3;i++) { printf("%d\n",fprintf(fp,"%s %lf %d\n",s1[i].name,s1[i].score,s1[i].age)); } rewind(fp); for(i=0;i<3;i++) { printf("%d\n",fscanf(fp,"%s %lf %d",s2[i].name,&s2[i].score,&s2[i].age)); } for(i=0;i<3;i++) { printf("%s %lf %d\n",s2[i].name,s2[i].score,s2[i].age); } fclose(fp); return 0;}
Execution result:
22
25
24
3
3
3
Liudehua 85.500000 45
Zhangxueyou 79.300000 47
Guofucheng 83.400000 43
Press any key to continue
The content in test.txt is:
If you change the open mode to "wt +", the content in the file is:
If you read and write data using fread and fwrite, the result is as follows:
Test procedure:
#include<stdio.h>#include<stdlib.h>typedef struct node{ char name[20]; double score; int age;}Student;int main(void){ FILE *fp; Student s1[3]={{"liudehua",85.5,45},{"zhangxueyou",79.3,47},{"guofucheng",83.4,43}}; if((fp=fopen("test.txt","wt+"))==NULL) { printf("can not open file\n"); exit(0); } fwrite(s1,sizeof(s1),1,fp); fclose(fp); return 0;}
The content in the file is:
We can see the difference between formatted read/write and other methods.
Test procedure:
#include<stdio.h>#include<stdlib.h>int main(void){ FILE *fp; int n=32768; if((fp=fopen("test.txt","wt+"))==NULL) { printf("can not open file\n"); exit(0); } fwrite(&n,sizeof(int),1,fp); fclose(fp); return 0;}
After execution, open the file in binary mode:
The binary value of 32768 is 00000000100000000000000, that is, 00 80 00, and the content occupies 4 bytes.
While
#include<stdio.h>#include<stdlib.h>int main(void){ FILE *fp; int n=32768; if((fp=fopen("test.txt","wt+"))==NULL) { printf("can not open file\n"); exit(0); } fprintf(fp,"%d",n); fclose(fp); return 0;}
Execution result:
That is, fprintf is used to write an integer of, 50, 55, 54, and 56, corresponding to the characters '3', '2', '7', '6', and '8, the content occupies 5 bytes.
Author Hai Zi