C file I/O SUPER detailed tutorial, o SUPER
This article mainly referencesC Primer Plus (5th & 6th Edition)
You can choose to read part of this article, some content may be too obscure to readers who are not familiar with MS-DOS.
Basic knowledge of C language files
Files are usually stored in a named storage area on a disk or SSD. All file content is stored in binary format. Files are divided into text files and binary files.
File Format |
Definition |
Save content |
Example |
Text Files |
A text file is a file that originally uses binary characters (such as ASCII or Unicode) to represent text. |
Text Content |
. TXT file |
Binary files |
A binary file is a file in which the binary value represents the machine language code or numerical data. |
Binary content |
Image File, Executable File |
The C language provides two ways to access files:Text modeAndBinary Mode. As the name implies, the text mode accesses a file in the form of text, which is usually a text file. Different systems process text files in different ways. UNIX systems use '\ n' to indicate line breaks, while early MS-DOS used' \ R' and '\ n' to combine line breaks and Ctrl + Z to indicate the end of the file. The old OS X Macintosh uses '\ R' to represent a new row. This makes it inconvenient for programmers to operate and use files in different systems. Fortunately, the C language provides a conversion mechanism. For example, if you open a file named file1.txt in the specified MS-DOS, it will automatically convert the \ r \ n combination to '\ n ', if you want to write content to the file, '\ n' is converted into a combination of \ r \ n. When a file is opened in binary mode, the program accesses every byte of the file. If a programmer needs to process a text file, he/she must take different measures based on the operating system.
The End of the File indicates the End of the File content. The C language uses the macro EOF (End of File) to indicate the End of the File. The value is usually-1.
C program automatically opens three files, which are:
File |
Default Device Used |
Representation in C program |
Standard Input |
Keyboard |
Stdin |
Standard output |
Display |
Stdout |
Standard Error output |
Display |
Stderr |
So how do I change the default device of these files? We can use the redirection method.
MS-DOS redirection
Using a computer with a MS-DOS6.22 system, assume that only C: \ user has the following file:
The file defin.txt contains the following content:
Insort.exe is a program for insert sorting.
To input defin.txt, execute the program:
It is found that the actually oriented input operator associates the content of defin.txt with the sdtin stream. '<' Indicates the redirection operator. This advantage is that if you encounter a large amount of data input, you can first input the data to the file, and then redirect the input to run the program, which is very convenient and easy to check and modify errors. There is no getch (); Execution content at the end of the listener, and the keyboard is no longer the default device of the stdin stream, so the program will never exit (single task pure DOS environment ). It can be seen that the redirection input is also risky. (Remind readers that when designing a program running in a single task pure DOS, you do not need to add a pause command at the end of the program if necessary. You must have an exit command)
Similarly, we can redirect the output:
In this case, all outputs are sent to defout.txt. '>' Indicates the target output identifier, which associates defout.txt with stdout. Open defout.txt and we can see:
In this case, the content on the display screen is input to the defout.txt file. However, you cannot see the output content, so the redirected output is only used in special cases, such as UNIX servers.
We can also use combination redirection.
<Defin.txt and> defout.txt can be used to change the location. Spaces between the left and right symbols can be omitted if allowed by the system.
Note that we cannot redirect multiple input or output files at the same time or link the redirected input and output to the executable file, when using redirection and File association, ensure that the File has an End Of EOF (End Of File). When using> Redirection output, the data in the output File will be overwritten.
File Open fopen () and close fclose () Functions
Using redirected input/output to operate files is not only cumbersome but also dangerous. The C language provides programmers with a more intuitive and convenient file access mechanism, that is, programmers can directly operate files in the program without having to perform "low-level" behavior such as redirection.
If you want to operate a file in the program, the file is in the same directory as the Program (if you want to use IDE to create it in the default path of IDE), you can open the file like this:
FILE * fp; // declare the FILE pointer fp = fopen ("file1.txt", "r"); // open the FILE in read-only mode if (fp = NULL) exit (EXIT_FAILURE); // exit if opening fails.
After the fopen () function is successfully opened, the pointer to the file is returned. Otherwise, NULL is returned. Two parameters are accepted. The first parameter indicates the name of the file (including the string address of the file name) and the second parameter indicates the open mode (which is the same as the text mode and binary mode, only these models are subdivided .), The common open mode is as follows:
In addition, the x mode is added for C11. This article will not detail in order not to increase the reader's burden.
Like dynamic memory allocation, we need to check whether the file is successfully opened, and it is necessary to close the file in time after the corresponding operations are completed. To close a file, we use fclose (), which is as simple as free () and has no return value:
Fclose (fp); // close the file if (fp! = 0) exit (EXIT_FAILURE); // exit if the shutdown fails.
However, sometimes files cannot be normally closed, for example, when the program runs, the hard disk fails or is pulled out. Therefore, it is necessary to check the status after it is disabled.
Single Character for text mode file I/O operations --- getc () and putc () Functions
C Primer Plus (Sixth Edition) has a clear explanation of the two functions :{
The getc () and putc () functions are similar to the getchar () and putchar () functions. The difference is that the getc () and putc () functions must be informed of which file to use. The following statement indicates "retrieving a character from the standard input ":
ch = getchar();
The following statement indicates "getting a character from the file specified by fp ":
ch = getc(fp);
Similarly, the following statement means "placing the character ch in the FILE specified by the FILE pointer fpout ":
putc(ch, fpout);
}
Here, we need to note that the return value of getc () is of the int type to return EOF. Although some systems define signed char by default for the char type, to ensure maximum portability of the program, in the above Code, the ch character is actually of the int type.
C programs will only find the end of the file (EOF) after reading the end of the file, so to avoid the error of reading the empty file, we should try to read the file before performing the corresponding operation, then, perform the corresponding operation based on whether or not to read the EOF.
Some readers may ask what is the relationship between getc (), fgetc (), putc (), and fputc? In fact, after reading the relevant documents, the two functions are almost identical, except that getc () and putc () are the macro implementations of fgetc () and fputc (). The original words are as follows:
Therefore, when getc () and putc () are called, their parameters cannot be expressions with side effects. For example, get (fp ++) is not allowed!
Format the input to the file --- fprintf () and fscanf () Functions
Fprintf (), fscanf (), printf (), and scanf () are similar, but a parameter is added to determine the output or input target file. For example, if a FILE pointer fp has specified a valid FILE and opened it in "w" mode, we can output Hello World to this FILE:
fprintf(fp, "Hello World");
Similarly, if a string "string" is saved at the beginning of the valid FILE specified by the FILE pointer fp and opened in "r" mode, in this way, input "string" to the array st:
fscanf(fp, "%s", st);
Please note that the input and output here do not refer to obtaining the input and output from the standard input and output device, but a transfer relationship:
We use an example on C Primer Plus (sort th Edition) to demonstrate the two functions and the specific applications of rewind:
String input and output to the file --- fgets () and fputs () Functions
Fgets () and fputs () functions have been introduced in the "input and output of strings" blog, but now they are extended to all files. Assuming that fp is a valid FILE pointer, read from the FILE specified by fp a string of SIZE-1 (excluding '\ 0') to the array st, we can do this:
Fgets (st, SIZE, stdin); // The fgets () function reads the SIZE-1 character or ends with '\ n, and assign the value of the last character or character after '\ n' to' \ 0', that is, it saves '\ n' in some cases '.
Similarly, fputs () outputs the string "Hello World \ n" to the file specified by fp:
Fputs (fp, "Hello World \ n"); // because fgets () saves '\ n', fput () does not automatically add' \ n' to the end of the string'
Binary mode file I/O File Location --- fseek () and ftell () Functions
Some readers may not be able to read it here, because we find that there are many functions related to file operations, which are hard to remember, but it doesn't matter. You don't have to memorize them, you just need to remember the general functions of the function, and then check the reference of the C standard library. Over time, you will remember it.
The ftell () function returns a long value, which indicates the number of bytes between the current position of the file and the start of the file. This determines the current position of the file pointer. It accepts a parameter, which indicates a valid file pointer. The following code assumes that fp is a valid FILE pointer:
long int addr;addr = ftell(fp);
Addr returns the current position of the file, as shown in:
It can be seen that ftell () treats the file as an array, and we can use the Array Processing method to process the file. However, there is an important premise that the file must be opened in binary mode, otherwise there will be meaningless results.
The fseek () function can change the current position of the file. The premise of its implementation should also be to open the file in binary mode. It accepts three parameters. The first parameter specifies the file pointer to be operated. The second parameter is calledOffsetThis is a long parameter. If the offset to the beginning of the file is a negative value, otherwise it is positive. The third parameter is the pattern used to indicate the starting point of the Offset. There are three modes:
We use examples in the book to explain the application of these two functions (because they are opened in binary mode, different implementation codes are required for reading text files in different systems ):
Binary I/O --- fread () and fwrite () Functions
We previously learned that if the C program accesses a file in binary mode, it will be able to access all bytes of the file. This feature is demonstrated in the file location example. So, why do I need to operate files in binary mode? If we want to store the value 1/3 in the file and select the text mode, the storage accuracy will be greatly reduced, it is also more troublesome (because a precision must be specified to convert numbers into strings, and the same precision must be specified during reading. If 1/3 is saved to a file as 0.33, the original precision cannot be restored after the next read ). Therefore, our best choice is to store values in the same bit format. We can use the sizeof (double) byte space to store 1/3, this is the same as the bit format of the double variable stored by the program in the memory. It is equivalent to copying a double variable with a value of 1/3 to the file and reading the variable according to the precision of the original write, the maximum precision can be restored. To complete the preceding operations, we can use fread () and fwrite () functions.
The original form of fwrite () is:
size_t fwrite(const void *
Ptr, size_t
Size, size_t
Nmemb, FILE *
Stream);
Ptr specifies the address (original address) of the data block to be written. size indicates the size of the data block to be written, nmemb indicates the number of data blocks to be written (which can be easily written to an array). stream specifies the file to be written (target address ). For example, if we want to write the number 1/3 to the file pro. dat with the maximum precision, we need to do this (this section only provides the core code ):
FILE * fp; double num = 1.0/3.0; fp = fopen ("pro. dat", "wb"); // open the FILE in binary write mode if (! Fp) exit (EXIT_FAILURE); fwrite (& num, sizeof (double), 1, fp); // write binary data if (fclose (fp )! = 0) // close the file exit (EXIT_FAILURE );
Then, we can check the folder in the same directory as the program and find that pro. dat is successfully created and the size is 8 bytes, which is exactly the size of the double type variable in the current system.
Now, if we want to read the content in the pro. dat file, we need to use the fread () function because garbled characters will appear when we open the file in text mode. The original form of the fread () function is as follows:
size_t fread(void *
Ptr, size_t
Size, size_t
Nmemb, FILE *
Stream);
It is also four parameters. The first parameter refers to the data block address (Destination Address) to be read. The second three parameters are the same as those in fwrite (), indicating the read size, the last parameter indicates the file to be read.
The following code demonstrates how to use the content of the pro. dat file:
FILE * fp; double get; fp = fopen ("pro. dat", "rb"); // open the FILE in binary read mode if (! Fp) exit (EXIT_FAILURE); fread (& get, sizeof (double), 1, fp); // read the file content to getif (fclose (fp )! = 0) // close the file in time exit (EXIT_FAILURE); printf ("get * 3.0 = % lf", get * 3.0); // output
If there is no accident, the code will be displayed after running:
Conclusion
In this article, I wrote a summary of the basic operations on C language files. If you have a C Primer Plus (version 5th or version 6) on hand, please read this article in conjunction with the book.
Through this article, we know:
> What is a file?
> Redirection operations and reflection problems in MS-DOS Systems
> Open and Close fopen () and fclose () of Text ()
> Text mode I/O: getc () and putc (), fprintf () and fscanf (), fgets () and fputs ()
> File Location: fseek () and ftell ()
> Binary mode I/O: fread () and fwrite ()
In the compilation process of this article, due to the large size of this article, there are many images, and some content is difficult, it took me a long time to complete. Errors in this article are inevitable. If you find any errors or suggestions after reading them, please criticize them!
Appendix: Other standard I/O functions (from C Primer Plus 5)