1. File Read/Write
C++ provides two main methods for file read/write operations: the C-style FILE* method and the C++ stream-based fstream method.
1) FILE File Pointer
<span>FILE</span> is a structure type defined in <stdio.h>, which includes information such as file descriptor, buffer information, current read/write position, and error and end-of-file flags.
Common Modes:
<span>"r"</span>– Read-only (file must exist)<span>"w"</span>– Write-only (create new file or clear existing file)<span>"a"</span>– Append (write at the end of the file)<span>"r+"</span>– Read/Write (file must exist)<span>"w+"</span>– Read/Write (create new file or clear existing file)<span>"a+"</span>– Read/Write (start from the end of the file)- Add
<span>"b"</span>to the mode string, e.g.,<span>"rb"</span>,<span>"wb+"</span>
//1. Open file FILE *fopen(const char *filename, const char *mode); //2. Close file int fclose(FILE *stream);//3. Formatted input/output int fprintf(FILE *stream, const char *format, ...); int fscanf(FILE *stream, const char *format, ...);//4. Character input/output int fgetc(FILE *stream); int fputc(int c, FILE *stream);//5. Line input/output char *fgets(char *str, int n, FILE *stream); int fputs(const char *str, FILE *stream);//6. Binary read/write size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);//7. File positioning int fseek(FILE *stream, long offset, int whence); long ftell(FILE *stream); void rewind(FILE *stream);//8. Error handling int feof(FILE *stream); // Check end-of-file flag int ferror(FILE *stream); // Check error flag void clearerr(FILE *stream); // Clear error flag//9. Buffer control int fflush(FILE *stream); // Force flush buffer void setbuf(FILE *stream, char *buf); // Set buffer int setvbuf(FILE *stream, char *buf, int mode, size_t size); // More fine control
Comprehensive example is as follows:
#include <stdio.h>#include <stdlib.h>int main() { // Write to file FILE *fp = fopen("example.dat", "w+"); if (!fp) { perror("File opening failed"); return EXIT_FAILURE; } fprintf(fp, "Text data: %d\n", 42); fputs("Another line\n", fp);
// Binary write double data[] = {1.1, 2.2, 3.3}; fwrite(data, sizeof(double), 3, fp);
// Go back to the beginning of the file rewind(fp);
// Read text char buffer[100]; while (fgets(buffer, sizeof(buffer), fp)) { printf("%s", buffer); }
// Check if end of file is reached if (feof(fp)) { printf("End of file reached.\n"); }
fclose(fp); return 0;}
2) fstream
<span>fstream</span> is a stream class in the C++ standard library used for file input/output, providing an object-oriented interface for file operations, which is safer and more aligned with C++ programming style than the C-style <span>FILE*</span> method. It mainly has two commonly used classes:
<span>ifstream</span>– for file input (reading)<span>ofstream</span>– for file output (writing)<span>fstream</span>– for bidirectional file operations (read/write)
Open File
First method: Constructor
std::ifstream inFile("input.txt"); // Open for read only std::ofstream outFile("output.txt"); // Open for write only std::fstream ioFile("data.txt", std::ios::in | std::ios::out); // Open for read/write
Second method: open method
std::fstream file; file.open("example.txt", std::ios::out | std::ios::app);
Common file opening modes can be combined
| Mode Flag | Description |
|---|---|
| std::ios::in | Read |
| std::ios::out | Write |
| std::ios::app | Append |
| std::ios::ate | Position at the end of the file when opened |
| std::ios::trunc | If the file exists, clear it |
| std::ios::binary | Binary mode |
Check File Status
if (file.is_open()) { /* File opened successfully */ } if (file.fail()) { /* Operation failed */ } if (file.eof()) { /* Reached end of file */ } if (file.good()) { /* All good */ }
Complete Example
#include <fstream>#include <iostream>#include <vector>int main() { // Write binary data { std::ofstream out("data.bin", std::ios::binary); if (!out) { std::cerr << "Cannot open file for writing!" << std::endl; return 1; }
std::vector<int> data = {1, 2, 3, 4, 5}; out.write(reinterpret_cast<const char*>(data.data()), data.size() * sizeof(int)); } // out goes out of scope, automatically closes // Read binary data { std::ifstream in("data.bin", std::ios::binary); if (!in) { std::cerr << "Cannot open file for reading!" << std::endl; return 1; }
// Get file size in.seekg(0, std::ios::end); size_t size = in.tellg(); in.seekg(0, std::ios::beg);
std::vector<int> data(size / sizeof(int)); in.read(reinterpret_cast<char*>(data.data()), size);
for (int n : data) { std::cout << n << " "; } std::cout << std::endl; } return 0;}
2. File Redirection
File redirection refers to the process of changing the program’s standard input/output streams (stdin/stdout/stderr) to other files or devices. In C++, file redirection can be achieved in various ways.
1) freopen
freopen is a file operation function in the C standard library used to reopen an existing file stream (such as stdin, stdout, stderr) and redirect it to another file or device. It is also available in C++.
#include <cstdio>int main() { // Redirect standard output to a file if (freopen("output.txt", "w", stdout) == NULL) { perror("Failed to redirect stdout"); return 1; }
printf("This will be written to the output.txt file\n");
// Restore standard output to console // Linux/macOS: freopen("/dev/tty", "w", stdout); // Windows: // freopen("CON", "w", stdout);
printf("This will be displayed on the console\n");
return 0;}
2) rdbuf()
rdbuf() is a core function in the C++ standard library used to manipulate stream buffers, providing direct access and control over stream buffers, which is a key mechanism for implementing stream redirection. It is the low-level abstraction of the C++ I/O system, responsible for actual data read/write operations, with each stream object (such as cout, ifstream) associated with a streambuf.
// Get current stream buffer std::streambuf* old_buffer = stream.rdbuf();// Set new stream buffer and return old std::streambuf* old_buffer = stream.rdbuf(new_buffer);
Specific example is as follows:
#include <iostream>#include <fstream>int main() { // Save original cout buffer std::streambuf* orig_buf = std::cout.rdbuf(); // Redirect to file std::ofstream out("output.txt"); std::cout.rdbuf(out.rdbuf()); std::cout << "This line will be written to output.txt file\n"; std::cout << 42 << " " << 3.14 << std::endl;
// Restore standard output std::cout.rdbuf(orig_buf); std::cout << "This line will be displayed on the console\n";
return 0;}