String, buffer and file operation
I/O Stream
Input/Output (I/O) operations in C++ are managed through a set of libraries that provide abstractions for handling streams of data. These libraries allow you to interact with various sources like the console, files, and strings seamlessly.
iostream
The <iostream>
library provides functionality for reading from and writing to the standard input (std::cin
) and standard output (std::cout
). It also includes error streams (std::cerr
and std::clog
).
Key Features:
Standard Input (
std::cin
):- Reads input from the console.
- Example:
int number; std::cin >> number; // Reads an integer from the user
Standard Output (
std::cout
):- Writes output to the console.
- Example:
std::cout << "Hello, World!" << std::endl;
Error Streams (
std::cerr
,std::clog
):std::cerr
: Unbuffered, used for immediate error messages.std::clog
: Buffered, used for logging diagnostic information.- Example:
std::cerr << "Error: Invalid input!" << std::endl;
fstream
The <fstream>
library extends the capabilities of <iostream>
to handle file-based input and output. It provides classes like std::ifstream
, std::ofstream
, and std::fstream
.
Key Classes:
std::ifstream
:- Used for reading data from files.
- Example:
std::ifstream inputFile("data.txt"); if (!inputFile.is_open()) { std::cerr << "Failed to open file!" << std::endl; }
std::ofstream
:- Used for writing data to files.
- Example:
std::ofstream outputFile("output.txt"); outputFile << "Writing to file." << std::endl;
std::fstream
:- Supports both reading and writing to files.
- Example:
std::fstream file("data.txt", std::ios::in | std::ios::out);
stringstream
The <sstream>
library allows you to treat strings as streams, enabling formatted input and output operations on strings.
Key Classes:
std::istringstream
:- Used for reading data from strings.
- Example:
std::string data = "42 3.14 Hello"; std::istringstream iss(data); int intValue; double doubleValue; std::string stringValue; iss >> intValue >> doubleValue >> stringValue;
std::ostringstream
:- Used for writing data to strings.
- Example:
std::ostringstream oss; oss << "Integer: " << 42 << ", Double: " << 3.14; std::string result = oss.str();
std::stringstream
:- Combines the functionality of
std::istringstream
andstd::ostringstream
. - Example:
std::stringstream ss; ss << "Hello" << " " << "World!"; std::string message = ss.str();
- Combines the functionality of
File Operation
File operations involve interacting with files on disk or other storage devices. The typical workflow follows the pattern: Open -> Perform Operations -> Close.
Open and Check
Before performing any file operation, you must ensure the file is successfully opened. This can be done using:
is_open()
:- Checks if the file stream is open.
- Example:
std::ifstream file("example.txt"); if (!file.is_open()) { std::cerr << "Failed to open file!" << std::endl; }
try-catch
Block:- Handles exceptions during file operations.
- Example:
try { std::ifstream file("example.txt"); if (!file) throw std::runtime_error("File not found!"); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; }
assert
:- Ensures the file is open during debugging.
- Example:
std::ifstream file("example.txt"); assert(file.is_open());
File Operation
Once the file is open, you can perform various operations such as reading, writing, appending, and binary file handling.
Reading from a File
- Use
>>
for formatted input orgetline()
for line-based input. - Example:
std::ifstream file("example.txt"); std::string line; while (std::getline(file, line)) { std::cout << line << std::endl; }
Writing to a File
- Use
<<
for formatted output. - Example:
std::ofstream file("output.txt"); file << "Writing to file." << std::endl;
Appending to a File
- Open the file in append mode (
std::ios::app
). - Example:
std::ofstream file("log.txt", std::ios::app); file << "Appending new line." << std::endl;
Binary File Handling
- Open the file in binary mode (
std::ios::binary
). - Example:
std::ofstream file("data.bin", std::ios::binary); int data = 42; file.write(reinterpret_cast<char*>(&data), sizeof(data));
Close the File
Closing the file ensures all buffered data is flushed and resources are released.
- Example:
file.close();
Buffer
A buffer is a temporary storage area used to hold data during input/output operations. Buffers improve performance by reducing direct interactions with slow devices like disks.
What is Buffer?
Buffers act as intermediaries between programs and external devices. They store data temporarily while it's being read from or written to a device.
Why Use Buffers?
- Optimize performance by batching I/O operations.
- Reduce the number of expensive system calls.
- Handle partial reads/writes gracefully.
Common API
Accessing Buffers:
- Use
rdbuf()
to access the underlying stream buffer. - Example:
std::ifstream file("example.txt"); std::streambuf* buf = file.rdbuf();
- Use
Flushing Buffers:
- Use
flush()
to manually flush the buffer. - Example:
std::cout << "Flushing buffer..." << std::flush;
- Use
Customizing Buffers:
- Use
pubsetbuf()
to set a custom buffer. - Example:
char buffer[1024]; std::ofstream file("output.txt"); file.rdbuf()->pubsetbuf(buffer, sizeof(buffer));
- Use
Disabling Buffering:
- Set the buffer size to 0 to disable buffering.
- Example:
file.rdbuf()->pubsetbuf(nullptr, 0);
Usage in File Operation
Buffers are integral to file operations, especially when dealing with large files or binary data.
Example: Copying File Content Using Buffers
#include <iostream>
#include <fstream>
int main() {
std::ifstream inputFile("source.txt", std::ios::binary);
std::ofstream outputFile("destination.txt", std::ios::binary);
if (!inputFile.is_open() || !outputFile.is_open()) {
std::cerr << "Failed to open files!" << std::endl;
return 1;
}
// Use buffers to copy file content
outputFile << inputFile.rdbuf();
inputFile.close();
outputFile.close();
return 0;
}
The buffer of filestream and stringstream are the same.