03 Input-Output Streams & Strings
Overview: Data Abstraction Streams
C++ replaces C’s formatting placeholders (like
%d,%sinprintf) with type-safe streams. Strings are elevated from raw character arrays to full object abstractions.
1. Input/Output Streams: Mechanics & Buffering
C++ standard input/output is built on stream classes: <iostream>.
std::cout: Standard output stream (buffered, routes to standard output).std::cin: Standard input stream (buffered, routes from standard input).std::cerr: Standard error stream (unbuffered, routes to standard error for instant output).
Operator Overloading at Work:
The operators << (insertion) and >> (extraction) are overloaded bitwise shift operators:
std::cout << "Value: " << myInt;
// Resolves to: std::operator<<(std::operator<<(std::cout, "Value: "), myInt);Each insertion returns a reference to the stream object (std::ostream&), allowing you to chain output calls.
Performance Tip: std::endl vs. '\n'
std::endlinserts a newline character and triggersstd::flushon the output buffer, forcing a system write call.- Using
std::endlinside loops can slow down execution due to repetitive flushing. Use'\n'instead, letting the system handle buffer flushes.
2. C++ Strings (std::string)
Unlike C-style character arrays, std::string is an instance of std::basic_string<char> that manages its own memory.
Memory Allocation & Small String Optimization (SSO)
- Dynamic Allocation: By default, strings allocate buffer memory on the heap to allow resizing.
- Small String Optimization (SSO): To avoid the overhead of heap allocations for short strings, modern compilers allocate a small buffer (typically 15 to 22 bytes) inside the string object itself on the stack.
Large String Object (Stack): [ Pointer to Heap ] ---> [ String characters on Heap ]
Small String Object (Stack): [ Embedded Buffer: "Hello\0" ] (No Heap allocation)
Mutability:
Unlike Java or Python strings, C++ strings are mutable. You can modify characters in place and append to them without creating a new object.
3. C-Style Strings vs. std::string
- C-Style string: A raw character array terminated by a null character
\0. Requires functions from<cstring>(e.g.strlen,strcmp). - Conversion: You can convert a
std::stringto a C-style string pointer using the.c_str()member function, which is useful when working with C-style legacy APIs.
💻 Conceptual Code Demonstration
#include <iostream>
#include <string>
#include <cstring> // For legacy C-string functions
int main() {
// 1. Stream input/output
std::cout << "Stream output: " << 42 << std::endl; // Forces flush
std::cout << "Stream output with newline: " << 100 << '\n'; // Faster
// 2. String mutability and methods
std::string text = "Hello";
text += " C++"; // Modifies string in place (concatenation)
text.append(" World"); // Heap expansion if SSO limit exceeded
std::cout << text << " | Length: " << text.length() << '\n';
// 3. Interacting with C-style strings
char legacyBuffer[20] = "Raw Array";
std::printf("C-string length: %zu\n", std::strlen(legacyBuffer));
// Converting std::string to const char*
const char* cStr = text.c_str(); // Returns a null-terminated pointer
std::printf("Legacy Print: %s\n", cStr);
return 0;
}