Skip to content
LAM
Read Home Blog
Make Projects HTML Tools Games
Touch grass Notes Resume Links
Home Blog HTML Projects
Tools Games Notes Resume Links
Back C++ Buffers: Visual Guide Programming
Download Open
Show description 1,962 chars · Programming

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

31,723 bytes · HTML source
<!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">&gt;&gt;</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&lt;streamsize&gt;::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 &lt;&lt; "Hello";     // Goes to buffer
cout &lt;&lt; " World";    // Still in buffer
// Output appears when buffer flushes
                    </div>
                </div>
                <div>
                    <h3 style="color: #64ffda;">Manual Flush</h3>
                    <div class="code-block">
cout &lt;&lt; "Hello" &lt;&lt; flush;  // Immediate output
cout &lt;&lt; " World" &lt;&lt; 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&lt;streamsize&gt;::max() for complete buffer clearing</strong>
            </div>

            <div class="code-block">
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;limits&gt;
using namespace std;

int main() {
    int number;
    string text;
    
    cout &lt;&lt; "Enter a number: " &lt;&lt; flush;  // Immediate prompt
    cin >> number;
    cin.ignore(numeric_limits&lt;streamsize&gt;::max(), '\n');  // Clear buffer
    
    cout &lt;&lt; "Enter text: " &lt;&lt; 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&lt;streamsize&gt;::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>