Show description
C++ Buffers: Visual Guide
C++ Buffers: Visual Guide
C++ Buffers: Interactive Visual Guide
What is a Buffer?
A buffer is a temporary storage area in memory that holds data during input/output operations. Think of it as a holding pen where data waits before being processed.
Input Buffer (8 characters)
Clear Buffer
cin and Input Buffering
When you use cin, data is first stored in an input buffer. The extraction operator (>>) reads from this buffer, but it leaves whitespace and newlines behind.
int number;
char character;
cin >> number; // Reads integer, leaves newline in buffer
cin >> character; // Might not work as expected!
cin Input Buffer
Simulate: cin >> int
Then: cin >> char
Reset
cin.ignore() - The Buffer Cleaner
cin.ignore() removes characters from the input buffer. It's essential for cleaning up after formatted input operations.
cin.ignore(); // Ignore next character
cin.ignore(100, '\n'); // Ignore up to 100 chars or until newline
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Ignore entire line
1
2
3
\n
a
b
c
\n
Buffer with leftover data
cin.ignore(1)
cin.ignore(4, '\n')
cin.ignore() all
Reset
Output Buffering and flush
Output operations like cout also use buffers. Data might not appear immediately on screen until the buffer is flushed.
Buffered Output
cout << "Hello"; // Goes to buffer
cout << " World"; // Still in buffer
// Output appears when buffer flushes
Manual Flush
cout << "Hello" << flush; // Immediate output
cout << " World" << endl; // endl flushes too
→
Terminal Output:
Add 'H'
Add 'ello'
Flush Buffer
Clear
Formatted vs Unformatted I/O
Formatted I/O (like cin >>) processes data according to type.…
C++ Buffers: Visual Guide
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>C++ Buffers: Visual Guide</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
background: linear-gradient(135deg, #0c0c0c 0%, #1a1a1a 100%);
color: #e0e0e0;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
font-size: 3rem;
background: linear-gradient(45deg, #64ffda, #00bcd4);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 2rem;
animation: glow 2s ease-in-out infinite alternate;
}
@keyframes glow {
from { text-shadow: 0 0 20px rgba(100, 255, 218, 0.3); }
to { text-shadow: 0 0 30px rgba(100, 255, 218, 0.6); }
}
.section {
margin: 3rem 0;
background: rgba(30, 30, 30, 0.8);
padding: 2rem;
border-radius: 12px;
border: 1px solid #333;
backdrop-filter: blur(10px);
}
.section h2 {
color: #64ffda;
margin-bottom: 1.5rem;
font-size: 1.8rem;
border-bottom: 2px solid #64ffda;
padding-bottom: 0.5rem;
}
.buffer-container {
display: flex;
align-items: center;
justify-content: center;
margin: 2rem 0;
flex-wrap: wrap;
gap: 2rem;
}
.buffer {
display: flex;
border: 2px solid #64ffda;
border-radius: 8px;
background: rgba(0, 0, 0, 0.5);
min-height: 60px;
align-items: center;
position: relative;
overflow: hidden;
}
.buffer-cell {
width: 40px;
height: 40px;
border: 1px solid #555;
display: flex;
align-items: center;
justify-content: center;
background: rgba(20, 20, 20, 0.8);
color: #fff;
font-size: 14px;
transition: all 0.3s ease;
margin: 2px;
}
.buffer-cell.filled {
background: linear-gradient(45deg, #ff6b6b, #ee5a24);
animation: pulse 0.5s ease;
}
.buffer-cell.reading {
background: linear-gradient(45deg, #54a0ff, #2e86de);
animation: reading 0.8s ease infinite;
}
@keyframes pulse {
0% { transform: scale(0.8); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
@keyframes reading {
0%, 100% { background: linear-gradient(45deg, #54a0ff, #2e86de); }
50% { background: linear-gradient(45deg, #00d2d3, #01a3a4); }
}
.data-flow {
width: 60px;
height: 4px;
background: linear-gradient(90deg, transparent, #64ffda, transparent);
margin: 0 1rem;
animation: flow 2s linear infinite;
position: relative;
}
@keyframes flow {
0% { transform: translateX(-100px); opacity: 0; }
50% { opacity: 1; }
100% { transform: translateX(100px); opacity: 0; }
}
.code-block {
background: #1a1a1a;
padding: 1.5rem;
border-radius: 8px;
border-left: 4px solid #64ffda;
font-family: 'Monaco', monospace;
margin: 1rem 0;
overflow-x: auto;
position: relative;
}
.code-block::before {
content: 'C++';
position: absolute;
top: -10px;
right: 10px;
background: #64ffda;
color: #000;
padding: 2px 8px;
font-size: 12px;
border-radius: 4px;
}
.interactive-demo {
background: rgba(40, 40, 40, 0.9);
padding: 2rem;
border-radius: 12px;
border: 2px solid #555;
margin: 1.5rem 0;
}
.demo-button {
background: linear-gradient(45deg, #64ffda, #00bcd4);
color: #000;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-weight: bold;
cursor: pointer;
margin: 0.5rem;
transition: all 0.3s ease;
font-family: inherit;
}
.demo-button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(100, 255, 218, 0.3);
}
.demo-button:active {
transform: translateY(0);
}
.input-field {
background: rgba(20, 20, 20, 0.8);
border: 2px solid #555;
color: #e0e0e0;
padding: 10px;
border-radius: 6px;
font-family: inherit;
margin: 0.5rem;
width: 200px;
}
.input-field:focus {
border-color: #64ffda;
outline: none;
box-shadow: 0 0 10px rgba(100, 255, 218, 0.3);
}
.explanation {
background: rgba(100, 255, 218, 0.1);
padding: 1rem;
border-radius: 8px;
border-left: 4px solid #64ffda;
margin: 1rem 0;
}
.terminal {
background: #000;
color: #00ff00;
padding: 1rem;
border-radius: 8px;
font-family: 'Courier New', monospace;
margin: 1rem 0;
min-height: 100px;
overflow-y: auto;
border: 1px solid #333;
}
.terminal-line {
margin: 0.2rem 0;
opacity: 0;
animation: typewriter 0.5s ease forwards;
}
@keyframes typewriter {
from { opacity: 0; transform: translateX(-10px); }
to { opacity: 1; transform: translateX(0); }
}
.arrow {
font-size: 24px;
color: #64ffda;
animation: bounce 1s ease infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
.buffer-label {
text-align: center;
color: #64ffda;
font-size: 12px;
margin-top: 0.5rem;
}
.comparison {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
margin: 2rem 0;
}
@media (max-width: 768px) {
.comparison {
grid-template-columns: 1fr;
}
.buffer-container {
flex-direction: column;
}
}
.highlight {
background: rgba(255, 107, 107, 0.2);
padding: 2px 4px;
border-radius: 3px;
color: #ff6b6b;
}
</style>
</head>
<body>
<div class="container">
<h1>C++ Buffers: Interactive Visual Guide</h1>
<div class="section">
<h2>What is a Buffer?</h2>
<div class="explanation">
A buffer is a temporary storage area in memory that holds data during input/output operations. Think of it as a holding pen where data waits before being processed.
</div>
<div class="buffer-container">
<div class="buffer" id="demo-buffer">
<div class="buffer-cell" data-char=""></div>
<div class="buffer-cell" data-char=""></div>
<div class="buffer-cell" data-char=""></div>
<div class="buffer-cell" data-char=""></div>
<div class="buffer-cell" data-char=""></div>
<div class="buffer-cell" data-char=""></div>
<div class="buffer-cell" data-char=""></div>
<div class="buffer-cell" data-char=""></div>
</div>
</div>
<div class="buffer-label">Input Buffer (8 characters)</div>
<div class="interactive-demo">
<input type="text" class="input-field" id="buffer-input" placeholder="Type something..." maxlength="8">
<button class="demo-button" onclick="clearBuffer()">Clear Buffer</button>
</div>
</div>
<div class="section">
<h2>cin and Input Buffering</h2>
<div class="explanation">
When you use <span class="highlight">cin</span>, data is first stored in an input buffer. The extraction operator (<span class="highlight">>></span>) reads from this buffer, but it leaves whitespace and newlines behind.
</div>
<div class="code-block">
int number;
char character;
cin >> number; // Reads integer, leaves newline in buffer
cin >> character; // Might not work as expected!
</div>
<div class="buffer-container">
<div class="buffer" id="cin-buffer">
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
</div>
</div>
<div class="buffer-label">cin Input Buffer</div>
<div class="interactive-demo">
<button class="demo-button" onclick="simulateCinInt()">Simulate: cin >> int</button>
<button class="demo-button" onclick="simulateCinChar()">Then: cin >> char</button>
<button class="demo-button" onclick="resetCinDemo()">Reset</button>
<div class="terminal" id="cin-terminal"></div>
</div>
</div>
<div class="section">
<h2>cin.ignore() - The Buffer Cleaner</h2>
<div class="explanation">
<span class="highlight">cin.ignore()</span> removes characters from the input buffer. It's essential for cleaning up after formatted input operations.
</div>
<div class="code-block">
cin.ignore(); // Ignore next character
cin.ignore(100, '\n'); // Ignore up to 100 chars or until newline
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Ignore entire line
</div>
<div class="buffer-container">
<div class="buffer" id="ignore-buffer">
<div class="buffer-cell">1</div>
<div class="buffer-cell">2</div>
<div class="buffer-cell">3</div>
<div class="buffer-cell">\n</div>
<div class="buffer-cell">a</div>
<div class="buffer-cell">b</div>
<div class="buffer-cell">c</div>
<div class="buffer-cell">\n</div>
</div>
</div>
<div class="buffer-label">Buffer with leftover data</div>
<div class="interactive-demo">
<button class="demo-button" onclick="demonstrateIgnore(1)">cin.ignore(1)</button>
<button class="demo-button" onclick="demonstrateIgnore(4)">cin.ignore(4, '\n')</button>
<button class="demo-button" onclick="demonstrateIgnore(-1)">cin.ignore() all</button>
<button class="demo-button" onclick="resetIgnoreDemo()">Reset</button>
<div class="terminal" id="ignore-terminal"></div>
</div>
</div>
<div class="section">
<h2>Output Buffering and flush</h2>
<div class="explanation">
Output operations like <span class="highlight">cout</span> also use buffers. Data might not appear immediately on screen until the buffer is flushed.
</div>
<div class="comparison">
<div>
<h3 style="color: #64ffda;">Buffered Output</h3>
<div class="code-block">
cout << "Hello"; // Goes to buffer
cout << " World"; // Still in buffer
// Output appears when buffer flushes
</div>
</div>
<div>
<h3 style="color: #64ffda;">Manual Flush</h3>
<div class="code-block">
cout << "Hello" << flush; // Immediate output
cout << " World" << endl; // endl flushes too
</div>
</div>
</div>
<div class="buffer-container">
<div class="buffer" id="output-buffer">
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
<div class="buffer-cell"></div>
</div>
<div class="arrow">→</div>
<div class="terminal" id="output-terminal" style="width: 300px; min-height: 80px;">
<div>Terminal Output:</div>
</div>
</div>
<div class="interactive-demo">
<button class="demo-button" onclick="addToOutputBuffer('H')">Add 'H'</button>
<button class="demo-button" onclick="addToOutputBuffer('ello')">Add 'ello'</button>
<button class="demo-button" onclick="flushOutputBuffer()">Flush Buffer</button>
<button class="demo-button" onclick="clearOutputDemo()">Clear</button>
</div>
</div>
<div class="section">
<h2>Formatted vs Unformatted I/O</h2>
<div class="explanation">
Formatted I/O (like <span class="highlight">cin >></span>) processes data according to type. Unformatted I/O (like <span class="highlight">getline</span>) reads raw characters.
</div>
<div class="comparison">
<div>
<h3 style="color: #ff6b6b;">Formatted Input</h3>
<div class="code-block">
int x;
cin >> x; // Skips whitespace, converts to int
</div>
<div class="buffer" id="formatted-buffer">
<div class="buffer-cell"> </div>
<div class="buffer-cell"> </div>
<div class="buffer-cell">1</div>
<div class="buffer-cell">2</div>
<div class="buffer-cell">3</div>
<div class="buffer-cell"> </div>
<div class="buffer-cell">x</div>
<div class="buffer-cell">y</div>
</div>
<div class="buffer-label">Only reads "123"</div>
</div>
<div>
<h3 style="color: #00d2d3;">Unformatted Input</h3>
<div class="code-block">
string line;
getline(cin, line); // Reads everything until newline
</div>
<div class="buffer" id="unformatted-buffer">
<div class="buffer-cell"> </div>
<div class="buffer-cell"> </div>
<div class="buffer-cell">1</div>
<div class="buffer-cell">2</div>
<div class="buffer-cell">3</div>
<div class="buffer-cell"> </div>
<div class="buffer-cell">x</div>
<div class="buffer-cell">y</div>
</div>
<div class="buffer-label">Reads " 123 xy"</div>
</div>
</div>
<div class="interactive-demo">
<button class="demo-button" onclick="demonstrateFormatted()">Show Formatted Read</button>
<button class="demo-button" onclick="demonstrateUnformatted()">Show Unformatted Read</button>
<div class="terminal" id="format-terminal"></div>
</div>
</div>
<div class="section">
<h2>String Input Problems</h2>
<div class="explanation">
Mixing <span class="highlight">cin >></span> and <span class="highlight">getline()</span> often causes problems because <span class="highlight">cin >></span> leaves the newline in the buffer.
</div>
<div class="code-block">
int age;
string name;
cin >> age; // Leaves '\n' in buffer
getline(cin, name); // Immediately reads the '\n' - gets empty string!
// Solution: Use cin.ignore()
cin >> age;
cin.ignore(); // Remove the newline
getline(cin, name); // Now works correctly
</div>
<div class="buffer-container">
<div class="buffer" id="string-buffer">
<div class="buffer-cell">2</div>
<div class="buffer-cell">5</div>
<div class="buffer-cell">\n</div>
<div class="buffer-cell">J</div>
<div class="buffer-cell">o</div>
<div class="buffer-cell">h</div>
<div class="buffer-cell">n</div>
<div class="buffer-cell">\n</div>
</div>
</div>
<div class="buffer-label">Buffer: "25\nJohn\n"</div>
<div class="interactive-demo">
<button class="demo-button" onclick="demonstrateStringProblem()">cin >> age (problem)</button>
<button class="demo-button" onclick="demonstrateStringFix()">cin >> age + ignore (fixed)</button>
<button class="demo-button" onclick="resetStringDemo()">Reset</button>
<div class="terminal" id="string-terminal"></div>
</div>
</div>
<div class="section">
<h2>Best Practices Summary</h2>
<div class="explanation">
<strong>1. Always use cin.ignore() after formatted input before getline()</strong><br>
<strong>2. Use flush or endl when you need immediate output</strong><br>
<strong>3. Understand the difference between formatted and unformatted I/O</strong><br>
<strong>4. Be aware that buffers can hold leftover data</strong><br>
<strong>5. Use numeric_limits<streamsize>::max() for complete buffer clearing</strong>
</div>
<div class="code-block">
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main() {
int number;
string text;
cout << "Enter a number: " << flush; // Immediate prompt
cin >> number;
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // Clear buffer
cout << "Enter text: " << flush;
getline(cin, text); // Now works perfectly
return 0;
}
</div>
</div>
</div>
<script>
// Buffer input demonstration
document.getElementById('buffer-input').addEventListener('input', function(e) {
const value = e.target.value;
const cells = document.querySelectorAll('#demo-buffer .buffer-cell');
cells.forEach((cell, index) => {
if (index < value.length) {
cell.textContent = value[index];
cell.classList.add('filled');
} else {
cell.textContent = '';
cell.classList.remove('filled');
}
});
});
function clearBuffer() {
document.getElementById('buffer-input').value = '';
const cells = document.querySelectorAll('#demo-buffer .buffer-cell');
cells.forEach(cell => {
cell.textContent = '';
cell.classList.remove('filled');
});
}
// cin demonstration
let cinState = 'initial';
function simulateCinInt() {
const terminal = document.getElementById('cin-terminal');
const buffer = document.querySelectorAll('#cin-buffer .buffer-cell');
terminal.innerHTML = '<div class="terminal-line">Input: "123\\nA"</div>';
// Fill buffer
setTimeout(() => {
buffer[0].textContent = '1';
buffer[0].classList.add('filled');
buffer[1].textContent = '2';
buffer[1].classList.add('filled');
buffer[2].textContent = '3';
buffer[2].classList.add('filled');
buffer[3].textContent = '\\n';
buffer[3].classList.add('filled');
buffer[4].textContent = 'A';
buffer[4].classList.add('filled');
}, 500);
// Show reading
setTimeout(() => {
buffer[0].classList.add('reading');
buffer[1].classList.add('reading');
buffer[2].classList.add('reading');
terminal.innerHTML += '<div class="terminal-line">cin >> number reads "123"</div>';
}, 1000);
setTimeout(() => {
buffer[0].textContent = '';
buffer[0].classList.remove('filled', 'reading');
buffer[1].textContent = '';
buffer[1].classList.remove('filled', 'reading');
buffer[2].textContent = '';
buffer[2].classList.remove('filled', 'reading');
terminal.innerHTML += '<div class="terminal-line">Buffer now: "\\nA"</div>';
cinState = 'after-int';
}, 1500);
}
function simulateCinChar() {
if (cinState !== 'after-int') {
document.getElementById('cin-terminal').innerHTML = '<div class="terminal-line">Run "cin >> int" first!</div>';
return;
}
const terminal = document.getElementById('cin-terminal');
const buffer = document.querySelectorAll('#cin-buffer .buffer-cell');
setTimeout(() => {
buffer[3].classList.add('reading');
terminal.innerHTML += '<div class="terminal-line">cin >> character reads "\\n" (newline!)</div>';
terminal.innerHTML += '<div class="terminal-line" style="color: #ff6b6b;">Problem: Got newline instead of \'A\'</div>';
}, 500);
}
function resetCinDemo() {
const buffer = document.querySelectorAll('#cin-buffer .buffer-cell');
buffer.forEach(cell => {
cell.textContent = '';
cell.classList.remove('filled', 'reading');
});
document.getElementById('cin-terminal').innerHTML = '';
cinState = 'initial';
}
// ignore demonstration
function demonstrateIgnore(count) {
const buffer = document.querySelectorAll('#ignore-buffer .buffer-cell');
const terminal = document.getElementById('ignore-terminal');
if (count === 1) {
buffer[0].style.opacity = '0.3';
terminal.innerHTML = '<div class="terminal-line">cin.ignore(1) - removed "1"</div>';
} else if (count === 4) {
for (let i = 0; i < 4; i++) {
buffer[i].style.opacity = '0.3';
}
terminal.innerHTML = '<div class="terminal-line">cin.ignore(4, \'\\n\') - removed "123\\n"</div>';
} else if (count === -1) {
buffer.forEach(cell => cell.style.opacity = '0.3');
terminal.innerHTML = '<div class="terminal-line">cin.ignore(numeric_limits<streamsize>::max(), \'\\n\') - cleared all</div>';
}
}
function resetIgnoreDemo() {
const buffer = document.querySelectorAll('#ignore-buffer .buffer-cell');
buffer.forEach(cell => cell.style.opacity = '1');
document.getElementById('ignore-terminal').innerHTML = '';
}
// Output buffer demonstration
let outputBuffer = [];
function addToOutputBuffer(text) {
const buffer = document.querySelectorAll('#output-buffer .buffer-cell');
for (let char of text) {
if (outputBuffer.length < 8) {
outputBuffer.push(char);
buffer[outputBuffer.length - 1].textContent = char;
buffer[outputBuffer.length - 1].classList.add('filled');
}
}
}
function flushOutputBuffer() {
const terminal = document.getElementById('output-terminal');
const buffer = document.querySelectorAll('#output-buffer .buffer-cell');
if (outputBuffer.length > 0) {
terminal.innerHTML += outputBuffer.join('');
outputBuffer = [];
buffer.forEach(cell => {
cell.textContent = '';
cell.classList.remove('filled');
});
}
}
function clearOutputDemo() {
const buffer = document.querySelectorAll('#output-buffer .buffer-cell');
document.getElementById('output-terminal').innerHTML = '<div>Terminal Output:</div>';
outputBuffer = [];
buffer.forEach(cell => {
cell.textContent = '';
cell.classList.remove('filled');
});
}
// Formatted vs unformatted demonstration
function demonstrateFormatted() {
const buffer = document.querySelectorAll('#formatted-buffer .buffer-cell');
const terminal = document.getElementById('format-terminal');
terminal.innerHTML = '<div class="terminal-line">Formatted input skips whitespace:</div>';
setTimeout(() => {
buffer[2].classList.add('reading');
buffer[3].classList.add('reading');
buffer[4].classList.add('reading');
terminal.innerHTML += '<div class="terminal-line">cin >> x reads only "123"</div>';
terminal.innerHTML += '<div class="terminal-line">Remaining in buffer: " xy"</div>';
}, 500);
}
function demonstrateUnformatted() {
const buffer = document.querySelectorAll('#unformatted-buffer .buffer-cell');
const terminal = document.getElementById('format-terminal');
terminal.innerHTML = '<div class="terminal-line">Unformatted input reads everything:</div>';
setTimeout(() => {
buffer.forEach(cell => cell.classList.add('reading'));
terminal.innerHTML += '<div class="terminal-line">getline() reads " 123 xy"</div>';
terminal.innerHTML += '<div class="terminal-line">Gets all characters until newline</div>';
}, 500);
}
// String input problem demonstration
function demonstrateStringProblem() {
const buffer = document.querySelectorAll('#string-buffer .buffer-cell');
const terminal = document.getElementById('string-terminal');
terminal.innerHTML = '<div class="terminal-line">cin >> age reads "25"</div>';
setTimeout(() => {
buffer[0].classList.add('reading');
buffer[1].classList.add('reading');
terminal.innerHTML += '<div class="terminal-line">Buffer now: "\\nJohn\\n"</div>';
}, 500);
setTimeout(() => {
buffer[0].classList.remove('reading');
buffer[1].classList.remove('reading');
buffer[2].classList.add('reading');
terminal.innerHTML += '<div class="terminal-line">getline(cin, name) reads "\\n"</div>';
terminal.innerHTML += '<div class="terminal-line" style="color: #ff6b6b;">Result: name = "" (empty string!)</div>';
}, 1500);
}
function demonstrateStringFix() {
const buffer = document.querySelectorAll('#string-buffer .buffer-cell');
const terminal = document.getElementById('string-terminal');
terminal.innerHTML = '<div class="terminal-line">cin >> age reads "25"</div>';
setTimeout(() => {
buffer[0].classList.add('reading');
buffer[1].classList.add('reading');
terminal.innerHTML += '<div class="terminal-line">cin.ignore() removes "\\n"</div>';
}, 500);
setTimeout(() => {
buffer[0].classList.remove('reading');
buffer[1].classList.remove('reading');
buffer[2].style.opacity = '0.3';
buffer[3].classList.add('reading');
buffer[4].classList.add('reading');
buffer[5].classList.add('reading');
buffer[6].classList.add('reading');
terminal.innerHTML += '<div class="terminal-line">getline(cin, name) reads "John"</div>';
terminal.innerHTML += '<div class="terminal-line" style="color: #64ffda;">Result: name = "John" ✓</div>';
}, 1500);
}
function resetStringDemo() {
const buffer = document.querySelectorAll('#string-buffer .buffer-cell');
buffer.forEach(cell => {
cell.style.opacity = '1';
cell.classList.remove('reading');
});
document.getElementById('string-terminal').innerHTML = '';
}
// Auto-clear reading states after animations
setInterval(() => {
document.querySelectorAll('.buffer-cell.reading').forEach(cell => {
if (!cell.matches(':hover')) {
cell.classList.remove('reading');
}
});
}, 2000);
</script>
</body>
</html>