FILE pointer
In C language, each used file opens up a corresponding file information area in the memory, which is used to store the related information of the file (such as the name of the file, the file status and the current location of the file, etc.). This information is stored in a structure variable. The structure type is declared by the system and named FILE. For example, the stdio.h header file provided by the VS2008 compilation environment has the following file type declaration:
struct _iobuf{
char*_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char*_tmpfname;
};
typedef struct _iobuf FILE;
The contents of the FILE type of different C compilers are not exactly the same, but they are similar. Whenever a file is opened, the system will automatically create a variable of the FILE structure according to the situation of the file, and fill in the information, so the user does not need to care about the details. Generally, a FILE pointer is used to maintain the variable of the FILE structure, which is more convenient to use.
Open and close files
open a file
The fopen function prototype:
FILE *fopen(const char *path, const char *mode);
Parameters: the first parameter is the file path, the second parameter is the way to open the file, the type is all string
Usage example
pFile = fopen("myfile.txt", "w");
#include <stdio.h>
int main(){
FILE* pFile;
pFile = fopen("myfile.txt", "w");
if (pFile != NULL) {
fputs("fopen example", pFile);
fclose(pFile);
}
return 0;
}
If there is no such file, a file will be created
The second parameter selection
File usage | meaning | If the specified file does not exist |
---|---|---|
"R" (read) | Open file for reading | Error |
"W" (write) | Truncate the file to zero length or create a text file for writing | Create a new file |
"Rt" (read only) 1 | Open a text file, only allow to read data | Error |
"Wt" (write only) | Write only to open or create a text file, only allow to write data | Create a new document |
"A" (addition) | Append data to the end of the text file | Error |
"Rb" (append) | Open a binary file for reading | Error |
"Wb" (write only) | Open a binary file for writing | Create a new file |
“Ab” (additional) | Add data to the end of a binary file | Error |
"R+" (read and write) | In order to read and write, open a text file | Error |
"W+" (read and write) | In order to read and write, create a new file | Create a new document |
"A+" (read and write) | Open a file, read and write at the end of the file | Create a new file |
"Rb+" (read and write) 2 | Open a binary file for reading and writing | Error |
"Wb+" (read and write) | In order to read and write, create a new binary file | Create a new file |
"Ab+" (read and write) | Open a binary file, read and write at the end of the file | Create a new file |
Close file
The fclose function prototype:
int fclose(FILE *stream);
Parameters: The only parameter is the file pointer that needs to be closed
File read and write
Sequential read and write
Features | Function name | Apply to |
---|---|---|
Character output function | fputc | All output streams |
Character input function | fgetc | All input streams |
Text line output function | fputs | All output streams |
Text line input function | fgets | All input streams |
Formatted output function | fprintf | All output streams |
Format input function | fscanf | All input streams |
Binary output | fwrite | file |
Binary input | fread | file |
The fputc function prototype:
int fputc( int c, FILE *stream );
Parameters: The first parameter is the character to be written, and the second parameter is the file stream to be written
Usage example
FILE* pFile = fopen("fputc.txt", "w");
char* str = "This is a test of fputc!!\n";
char* p_str = str;
while ((*p_str != '\0') && fputc(*(p_str++), stdout) != EOF);
p_str = str;
while ((*p_str != '\0') && fputc(*(p_str++), pFile) != EOF);
The FILE pointer is actually a file stream, which is also a kind of stream, which is almost the same as the standard input and output stream.
The fgetc function prototype:
int fgetc( FILE *stream );
Parameters: stream is the destination stream to be read
Usage example
//先使用fputs写一个文本文件
FILE* pFile = fopen("fgetc.txt", "w");
char* str = "This is a test of fgetc!!\n";
fputs("Hello world from fgetc.\n", pFile);
fclose(pFile);
//使用fgetc读取这个文本文件的内容
pFile = fopen("fgetc.txt", "r");
while(feof(pFile) == 0){
char ch = fgetc(pFile);
fputc((char)ch, stdout);
}
fclose(pFile);
The fputs function prototype:
int fputs( const char *string, FILE *stream );
Parameters: the first is the string to be written to the file, the second parameter is the output stream
Usage example
FILE* pFile = fopen("fputs.txt", "w");
char* str = "This is a test of fputs!!\n";
fputs(str, pFile);
The fgets function prototype:
char *fgets(char *restrict s, int n, FILE *restrict stream);
Parameters: read a string of up to n characters from the stream and save it to the s character
Usage example
//先使用fputs写入一个文本文件
FILE* pFile = fopen("fgets.txt", "w");
char* str = "This is a test of fgets!!\n";
fputs(str, pFile);
fclose(pFile);
//再使用fgets读
char line[1000];
if ((pFile = fopen("fgets.txt", "r")) != NULL)
{
if (fgets(line, 1000, pFile) == NULL)
printf("fgets error\n");
else
printf("%s", line);
fclose(pFile);
}
The fprintf function prototype:
int fprintf( FILE *stream, const char *format [, argument ]...);
Parameters: stream the stream to be output, format is the format control string, argument is multiple variables
Usage example
int i = 10;
double fp = 1.5;
char s[] = "this is a string";
char c = '\n';
FILE* stream = fopen("fprintf.out", "w");
fprintf(stream, "%s%c", s, c);
fprintf(stream, "%d\n", i);
fprintf(stream, "%f\n", fp);
fclose(stream);
system("type fprintf.out");
The difference between printf and standard output is that the first specified output stream parameter is added. The content of the out suffix file can be directly printed to the standard output stream using system.
The fscanf function prototype:
int fscanf( FILE *stream, const char *format [, argument ]... );
Parameters: parse the data from the stream according to format and store them in arguments in turn
Usage example
//先使用fprintf向文件输入
int i = 10;
double fp = 1.5;
char s[] = "string";
char c = 'U';
FILE* stream = fopen("fscanf.out", "w");
fprintf(stream, "%s %c", s, c);
//s字符串需要scanf读取的话,没有空格和换行的字符串请用空格与后面的变量隔开,如果字符串含空格,建议将字符串作为一整行用fgets读取
fprintf(stream, "%d\n", i);
fprintf(stream, "%f\n", fp);
fclose(stream);
//使用fscanf读取文件数据
stream = fopen("fscanf.out", "r");
fscanf(stream, "%s", &s);
fscanf(stream, "%c", &c); //捕捉空格
fscanf(stream, "%c", &c);
printf("%s %c\n", s, c);
fscanf(stream, "%d", &i);
fscanf(stream, "%f", &fp);
printf("%d\n%f\n", i, fp);
fclose(stream);
The fwrite function prototype:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
Parameters: buffer is the data to be written, size is the byte size of the element, count is the number of elements, stream is the destination stream to be written
Usage example
FILE* stream = fopen("fwrite.out", "w+t");
char list[] = "abcdefghijklmnopqrstuvwxyz";
if (stream != NULL) {
char numwritten = fwrite(list, sizeof(char), strlen(list), stream);
printf("Wrote %d items\n", numwritten);
fclose(stream);
}
system("type fread.out");
fwrite can write count characters, integer or size strings
The fread function prototype:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
Parameters: buffer is the data storage area to be read, size is the size of a single element, count is
Usage example
//读取上面fwrite保存的fwrite.out文件
if ((stream = fopen("fwrite.out", "r+t")) != NULL)
{
char numread = fread(list, sizeof(char), 26, stream);
printf("Number of items read = %d\n", numread);
printf("Contents of buffer = %.26s\n", list);
fclose(stream);
}
else
printf("File could not be opened\n");
Random read and write
Jump to any position of the file pointer
fseek function prototype
int fseek(FILE * stream, long int offset, int origin);
Parameters: stream is the stream being operated on, offset is the offset, origin is the starting position of the reference offset
Benchmark | Offset reference position |
---|---|
SEEK_SET | Start of file |
SEEK_CUR | The current position pointed to by the file pointer |
SEEK_END | End of file |
Usage example
FILE* pFile = fopen("example.txt", "wb");
fputs("This is an apple.", pFile);
fseek(pFile, 9, SEEK_SET);
fputs(" sam", pFile);
fclose(pFile);
system("type example.txt");
Returns the offset of the file pointer relative to the starting position
ftell function prototype
long ftell( FILE *stream );
Parameters: stream is the target stream to get the offset
Usage example
FILE* stream = fopen("ftell.c", "w+");
srand(time(NULL));
int charNumber = 150;
while (charNumber--)
fputc(rand() % 57 + 65, stream);
//得到当前的偏移量
long position;
position = ftell(stream);
printf("Position after trying to read 100 bytes: %ld\n",
position);
fclose(stream);
The position of the file pointer returns to the beginning of the file
rewind function prototype
void rewind ( FILE * stream );
Parameters: stream is the target stream that points the file pointer to the beginning of the file
Usage example
//写一个文件用于测试
char list[100];
FILE* stream = fopen("rewind.c", "w");
srand(time(NULL));
int charNumber = 150;
while (charNumber--)
fputc(rand() % 57 + 65, stream);
fclose(stream);
stream = fopen("rewind.c", "r");
//读
fread(list, sizeof(char), 100, stream);
char position = ftell(stream);
printf("Position after read: %ld\n",
position);
//文件指针回到文件首
rewind(stream);
position = ftell(stream);
printf("Position after back to start: %ld\n",
position);
fclose(stream);
Just finish writing and do not close the file stream to read the file fingerprint offset is a negative number
FILE* stream = fopen("rewind.c", "w");
srand(time(NULL));
int charNumber = 150;
while (charNumber--)
fputc(rand() % 57 + 65, stream);
char position = ftell(stream);
printf("Position after write: %ld\n", position);
File end judgment
feof function prototype
int feof( FILE *stream );
Parameters: Determine whether the file pointer reaches the target stream at the end of the file
fgetc, fgetc, fread, fprintf will return EOF when the end of the file is read
Usage example
//创建feof.c
FILE* stream = fopen("feof.c", "w");
srand(time(NULL));
int charNumber = 80;
while (charNumber--)
fputc(rand() % 57 + 65, stream);
fclose(stream);
//读feof.c
int count, total = 0;
char buffer[100];
if ((stream = fopen("feof.c", "r")) == NULL)
exit(1);
//结合feof就可以循环读到文件结尾
/* Cycle until end of file reached: */
while (!feof(stream))
{
/* Attempt to read in 10 bytes: */
count = fread(buffer, sizeof(char), 100, stream);
if (ferror(stream)) {
perror("Read error");
break;
}
/* Total up actual bytes read */
total += count;
}
printf("Number of bytes read = %d\n", total);
fclose(stream);
Example of reading a binary file
#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{
double a[SIZE] = { 1.0,2.0,3.0,4.0,5.0 };
double b = 0.0;
size_t ret_code = 0;
FILE* fp = fopen("test.bin", "wb"); // 必须用二进制模式
fwrite(a, sizeof(*a), SIZE, fp); // 写 double 的数组
fclose(fp);
fp = fopen("test.bin", "rb");
// 读 double 的数组
while ((ret_code = fread(&b, sizeof(double), 1, fp)) >= 1)
{
printf("%lf\n", b);
}
if (feof(fp))
printf("Error reading test.bin: unexpected end of file\n");
else if (ferror(fp)) {
perror("Error reading test.bin");
}
fclose(fp);
fp = NULL;
}