📌 What is File Handling?
Imagine writing your homework in a notebook — if you don’t write it down and just keep it in your head, it’s lost when you sleep or get distracted.
Similarly, when a program runs, all the data is stored in temporary memory (RAM). Once the program ends, everything is erased.
So, if we want to:
Save data permanently ✅
Share data with other programs or people ✅
Maintain logs, backups, settings ✅
We need to store that data in a file.
👉 That’s where File Handling in C comes in — it allows your C program to create, read, write, append, and manipulate files on disk using specific functions from the standard library (stdio.h).
<div class="infographic-cfile">
<style>
.infographic-cfile {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--warn: #b45309;
--warn-soft: #fdf0dc;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
}
.infographic-cfile[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--warn: #e0a458;
--warn-soft: #3a2c14;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-cfile {
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1rem, 4vw, 2.25rem) 1.25rem;
}
.infographic-cfile *, .infographic-cfile *::before, .infographic-cfile *::after {
box-sizing: border-box;
}
.infographic-cfile h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.3rem, 3.5vw, 1.7rem);
margin: 1.25rem 0 0.2rem;
text-align: center;
}
.infographic-cfile .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1.3rem; text-align: center; }
.infographic-cfile .scene {
position: relative;
display: flex;
align-items: flex-end;
justify-content: center;
gap: 3.5rem;
padding: 1.5rem 0.5rem 1rem;
min-height: 9rem;
}
.infographic-cfile .box-wrap { text-align: center; }
.infographic-cfile .box {
width: 6.5rem;
height: 5.5rem;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 1.6rem;
position: relative;
transition: opacity 0.6s ease, border-color 0.4s ease, background 0.4s ease;
}
.infographic-cfile .box.ram {
border: 2.5px dashed var(--line);
background: var(--paper-alt);
}
.infographic-cfile .box.ram.has-data { border-color: var(--accent); background: var(--accent-soft); }
.infographic-cfile .box.ram.is-cleared { opacity: 0.3; }
.infographic-cfile .box.disk {
border: 2.5px solid var(--line);
background: var(--paper-alt);
}
.infographic-cfile .box.disk.has-data { border-color: var(--ok); background: var(--ok-soft); }
.infographic-cfile .box-label { font-family: 'IBM Plex Mono', monospace; font-size: 0.75rem; color: var(--ink-soft); margin-top: 0.5rem; }
.infographic-cfile .data-pill {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
font-weight: 700;
padding: 0.2rem 0.5rem;
border-radius: 12px;
background: var(--paper);
color: var(--ink-soft);
opacity: 0;
transform: scale(0.7);
transition: opacity 0.35s ease, transform 0.35s ease;
}
.infographic-cfile .box.has-data .data-pill { opacity: 1; transform: scale(1); color: var(--ink); }
.infographic-cfile .arrow-mid { font-size: 1.4rem; color: var(--ink-soft); opacity: 0; transition: opacity 0.4s ease; }
.infographic-cfile .arrow-mid.is-visible { opacity: 1; }
.infographic-cfile .step-caption {
text-align: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
color: var(--accent);
min-height: 1.4rem;
margin-bottom: 1rem;
}
.infographic-cfile .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; }
.infographic-cfile .ctrl-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem; font-weight: 600;
padding: 0.45rem 1rem;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--paper-alt);
color: var(--ink);
}
.infographic-cfile .ctrl-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.infographic-cfile .ctrl-btn:hover { border-color: var(--accent); }
.infographic-cfile .ctrl-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-cfile .fn-strip {
display: flex;
justify-content: center;
gap: 0.4rem;
margin-top: 1.3rem;
flex-wrap: wrap;
}
.infographic-cfile .fn-tag {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.72rem;
padding: 0.3rem 0.6rem;
border-radius: 6px;
background: var(--paper-alt);
color: var(--ink-soft);
border: 1px solid var(--line);
transition: border-color 0.3s, background 0.3s, color 0.3s;
}
.infographic-cfile .fn-tag.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.infographic-cfile .takeaway {
font-size: 0.82rem; color: var(--ink-soft);
margin-top: 1.4rem; border-top: 1px solid var(--line); padding-top: 0.9rem;
text-align: center;
}
.infographic-cfile .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cfile * { transition: none !important; }
}
</style>
<h1>📁 File Handling in C</h1>
<p class="subhead">RAM forgets. A file remembers.</p>
<div class="scene">
<div class="box-wrap">
<div class="box ram" id="ram-box">
<span>🧠</span>
<div class="data-pill" id="ram-pill">Hi</div>
</div>
<div class="box-label">RAM</div>
</div>
<div class="arrow-mid" id="mid-arrow">→</div>
<div class="box-wrap">
<div class="box disk" id="disk-box">
<span>💾</span>
<div class="data-pill" id="disk-pill">Hi</div>
</div>
<div class="box-label">file.txt</div>
</div>
</div>
<p class="step-caption" id="step-caption"> </p>
<div class="controls">
<button class="ctrl-btn primary" id="play-btn">▶ Play</button>
<button class="ctrl-btn" id="restart-btn">⟲ Restart</button>
</div>
<div class="fn-strip">
<span class="fn-tag" id="fn-fopen">fopen()</span>
<span class="fn-tag" id="fn-write">fprintf()</span>
<span class="fn-tag" id="fn-close">fclose()</span>
<span class="fn-tag" id="fn-reopen">fopen()</span>
<span class="fn-tag" id="fn-read">fscanf()</span>
</div>
<p class="takeaway"><strong>The notebook rule:</strong> whatever's only in RAM disappears when the program ends — whatever's written to a file is still there next time.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cfile')
|| document.querySelector('.infographic-cfile');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function $(sel) { return wrapper.querySelector(sel); }
const ramBox = $('#ram-box'), diskBox = $('#disk-box');
const midArrow = $('#mid-arrow');
const caption = $('#step-caption');
const playBtn = $('#play-btn'), restartBtn = $('#restart-btn');
const fnTags = {
fopen: $('#fn-fopen'), write: $('#fn-write'), close: $('#fn-close'),
reopen: $('#fn-reopen'), read: $('#fn-read')
};
function clearFns() { Object.values(fnTags).forEach(t => t.classList.remove('is-active')); }
const steps = [
{
caption: 'program runs — data lives in RAM',
run: () => { ramBox.classList.add('has-data'); clearFns(); }
},
{
caption: 'fopen() + fprintf() — write it to disk',
run: () => { clearFns(); fnTags.fopen.classList.add('is-active'); fnTags.write.classList.add('is-active'); midArrow.classList.add('is-visible'); diskBox.classList.add('has-data'); }
},
{
caption: 'fclose() — program ends, RAM is wiped',
run: () => { clearFns(); fnTags.close.classList.add('is-active'); ramBox.classList.add('is-cleared'); ramBox.classList.remove('has-data'); midArrow.classList.remove('is-visible'); }
},
{
caption: 'later: fopen() + fscanf() — read it back',
run: () => { clearFns(); fnTags.reopen.classList.add('is-active'); fnTags.read.classList.add('is-active'); ramBox.classList.remove('is-cleared'); ramBox.classList.add('has-data'); midArrow.classList.add('is-visible'); }
},
{
caption: 'file.txt still had it — nothing was lost',
run: () => { clearFns(); }
}
];
let idx = -1;
let timer = null;
let playing = false;
function reset() {
clearTimeout(timer);
playing = false;
idx = -1;
playBtn.disabled = false;
playBtn.textContent = '▶ Play';
ramBox.classList.remove('has-data', 'is-cleared');
diskBox.classList.remove('has-data');
midArrow.classList.remove('is-visible');
clearFns();
caption.innerHTML = ' ';
}
function advance() {
idx++;
if (idx >= steps.length) { stop(); return; }
steps[idx].run();
caption.textContent = steps[idx].caption;
if (idx >= steps.length - 1) stop();
else timer = setTimeout(advance, 1500);
}
function stop() {
playing = false;
clearTimeout(timer);
playBtn.disabled = false;
playBtn.textContent = '▶ Play';
}
playBtn.addEventListener('click', () => {
if (playing) return;
if (idx >= steps.length - 1) reset();
playing = true;
playBtn.disabled = true;
playBtn.textContent = '⏸ Playing…';
advance();
});
restartBtn.addEventListener('click', reset);
reset();
})();
</script>🔁 Why File Handling is Needed?
Without Files | With File Handling |
|---|---|
Data lost after program ends ❌ | Data is stored permanently ✅ |
Cannot share output ❌ | Output can be shared via files ✅ |
Manual re-entry needed ❌ | Reuse stored data anytime ✅ |
📦 Types of Files in C
Text Files (.txt)
Data is stored as readable characters
Can open the file in Notepad or any editor
E.g.,
report.txt,log.txtUsed for config, reports, user data
Binary Files (.bin)
Data is stored in binary format (0s and 1s)
Not readable by humans
Smaller, faster, more efficient
Used for high-performance apps, storing structures, images, etc.
⚙️ Core File Operations in C
All file handling is done through a file pointer, using the FILE type from the C standard library.
#include <stdio.h>
FILE *fp; // file pointer🟢 Opening a File – fopen()
<div class="infographic-cfopen">
<style>
.infographic-cfopen {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--code-bg: #1e1e2e;
--code-text: #d4d4e0;
--syn-keyword: #c586c0;
--syn-func: #dcdcaa;
--syn-string: #ce9178;
--warn: #b45309;
--warn-soft: #fdf0dc;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
}
.infographic-cfopen[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--code-bg: #0d0d14;
--code-text: #d4d4e0;
--warn: #e0a458;
--warn-soft: #3a2c14;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-cfopen {
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1rem, 4vw, 2.25rem) 1.25rem;
}
.infographic-cfopen *, .infographic-cfopen *::before, .infographic-cfopen *::after {
box-sizing: border-box;
}
.infographic-cfopen h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.3rem, 3.5vw, 1.7rem);
margin: 1.25rem 0 0.2rem;
text-align: center;
}
.infographic-cfopen .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1.1rem; text-align: center; }
.infographic-cfopen .code-panel {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.6rem 0.9rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
margin-bottom: 1rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
text-align: center;
}
.infographic-cfopen .syn-keyword { color: var(--syn-keyword); }
.infographic-cfopen .syn-func { color: var(--syn-func); }
.infographic-cfopen .syn-string { color: var(--syn-string); }
.infographic-cfopen .chip-row { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 0.8rem; flex-wrap: wrap; }
.infographic-cfopen .chip {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 700;
padding: 0.38rem 0.75rem;
border-radius: 8px;
border: 1px solid var(--line);
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.infographic-cfopen .chip:hover { border-color: var(--accent); }
.infographic-cfopen .chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.infographic-cfopen .toggle-row { display: flex; justify-content: center; align-items: center; gap: 0.5rem; margin-bottom: 1rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.82rem; color: var(--ink-soft); }
.infographic-cfopen .toggle-row input { width: 1.1rem; height: 1.1rem; accent-color: var(--accent); }
.infographic-cfopen .run-btn {
all: unset; cursor: pointer;
display: block;
margin: 0 auto 1.2rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem; font-weight: 600;
padding: 0.48rem 1.1rem;
border-radius: 999px;
background: var(--accent);
color: #fff;
}
.infographic-cfopen .run-btn:hover { opacity: 0.88; }
.infographic-cfopen .scene {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 2.6rem;
padding: 1rem 0.5rem 1.3rem;
}
.infographic-cfopen .fp-box {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
font-weight: 700;
padding: 0.6rem 0.9rem;
border: 2px solid var(--line);
border-radius: 8px;
background: var(--paper-alt);
color: var(--ink-soft);
text-align: center;
transition: border-color 0.3s, background 0.3s, color 0.3s;
}
.infographic-cfopen .fp-box.is-ok { border-color: var(--ok); background: var(--ok-soft); color: var(--ok); }
.infographic-cfopen .fp-box.is-null { border-color: var(--warn); background: var(--warn-soft); color: var(--warn); }
.infographic-cfopen .fp-name { font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; color: var(--ink-soft); margin-top: 0.35rem; text-align: center; }
.infographic-cfopen .arrow-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.infographic-cfopen .arrow-path { fill: none; stroke: var(--ok); stroke-width: 2.2; stroke-dasharray: 130; stroke-dashoffset: 130; opacity: 0; transition: stroke-dashoffset 0.4s ease, opacity 0.3s ease; }
.infographic-cfopen .arrow-path.is-visible { stroke-dashoffset: 0; opacity: 1; }
.infographic-cfopen .arrow-head { fill: var(--ok); opacity: 0; transition: opacity 0.3s ease 0.25s; }
.infographic-cfopen .arrow-head.is-visible { opacity: 1; }
.infographic-cfopen .file-box {
border: 2px solid var(--line);
border-radius: 10px;
background: var(--paper-alt);
padding: 0.6rem 0.8rem;
min-width: 9rem;
text-align: center;
transition: border-color 0.3s, background 0.3s;
}
.infographic-cfopen .file-box.is-active { border-color: var(--accent); background: var(--accent-soft); }
.infographic-cfopen .file-icon { font-size: 1.4rem; }
.infographic-cfopen .file-content {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.72rem;
color: var(--ink);
margin-top: 0.4rem;
min-height: 1.2rem;
word-break: break-word;
}
.infographic-cfopen .file-cursor { color: var(--accent); font-weight: 700; }
.infographic-cfopen .result-note {
text-align: center;
font-size: 0.82rem;
font-weight: 600;
min-height: 1.2rem;
margin-bottom: 1rem;
}
.infographic-cfopen .result-note.ok { color: var(--ok); }
.infographic-cfopen .result-note.warn { color: var(--warn); }
.infographic-cfopen table.mode-ref {
border-collapse: collapse;
width: 100%;
font-size: 0.76rem;
margin-top: 0.3rem;
}
.infographic-cfopen table.mode-ref th, .infographic-cfopen table.mode-ref td {
border: 1px solid var(--line);
padding: 0.35rem 0.5rem;
text-align: left;
}
.infographic-cfopen table.mode-ref th {
background: var(--paper-alt);
font-size: 0.66rem;
text-transform: uppercase;
color: var(--ink-soft);
}
.infographic-cfopen table.mode-ref td:first-child { font-family: 'IBM Plex Mono', monospace; font-weight: 700; }
.infographic-cfopen table.mode-ref tr.is-active-row td { background: var(--accent-soft); }
.infographic-cfopen .takeaway {
font-size: 0.82rem; color: var(--ink-soft);
margin-top: 1.3rem; border-top: 1px solid var(--line); padding-top: 0.9rem;
}
.infographic-cfopen .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cfopen * { transition: none !important; }
}
</style>
<h1>🟢 fopen()</h1>
<p class="subhead">Same file, six modes — very different results.</p>
<div class="code-panel" id="fo-code">FILE *fp = fopen("data.txt", "r");</div>
<div class="chip-row" id="mode-chips">
<button class="chip is-active" data-mode="r">r</button>
<button class="chip" data-mode="w">w</button>
<button class="chip" data-mode="a">a</button>
<button class="chip" data-mode="r+">r+</button>
<button class="chip" data-mode="w+">w+</button>
<button class="chip" data-mode="a+">a+</button>
</div>
<div class="toggle-row">
<input type="checkbox" id="exists-toggle" checked>
<label for="exists-toggle">data.txt already exists (contains "Hello")</label>
</div>
<button class="run-btn" id="fo-run">▶ Run fopen()</button>
<div class="scene" id="fo-scene">
<svg class="arrow-svg" id="fo-arrow-svg">
<path class="arrow-path" id="fo-arrow-path" d=""></path>
<polygon class="arrow-head" id="fo-arrow-head" points=""></polygon>
</svg>
<div>
<div class="fp-box" id="fp-box">?</div>
<div class="fp-name">fp</div>
</div>
<div class="file-box" id="file-box">
<div class="file-icon">📄</div>
<div class="file-content" id="file-content">Hello</div>
</div>
</div>
<p class="result-note" id="fo-result"></p>
<table class="mode-ref" id="mode-ref">
<tr><th>Mode</th><th>Meaning</th></tr>
<tr data-mode="r"><td>r</td><td>Read (file must exist)</td></tr>
<tr data-mode="w"><td>w</td><td>Write (overwrite or create)</td></tr>
<tr data-mode="a"><td>a</td><td>Append (add to end)</td></tr>
<tr data-mode="r+"><td>r+</td><td>Read + write</td></tr>
<tr data-mode="w+"><td>w+</td><td>Read + write (overwrite)</td></tr>
<tr data-mode="a+"><td>a+</td><td>Read + append</td></tr>
</table>
<p class="takeaway"><strong>Try it:</strong> uncheck "already exists" and run mode <code style="font-family:'IBM Plex Mono',monospace;">r</code> — that's the classic fopen() failure, fp comes back NULL.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cfopen')
|| document.querySelector('.infographic-cfopen');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function $(sel) { return wrapper.querySelector(sel); }
const codeEl = $('#fo-code');
const chips = wrapper.querySelectorAll('#mode-chips .chip');
const existsToggle = $('#exists-toggle');
const runBtn = $('#fo-run');
const fpBox = $('#fp-box');
const fileBox = $('#file-box');
const fileContent = $('#file-content');
const resultNote = $('#fo-result');
const arrowPath = $('#fo-arrow-path');
const arrowHead = $('#fo-arrow-head');
const scene = $('#fo-scene');
const svg = $('#fo-arrow-svg');
const refRows = wrapper.querySelectorAll('#mode-ref tr[data-mode]');
let mode = 'r';
const ORIGINAL_CONTENT = 'Hello';
function updateCode() {
codeEl.textContent = '';
codeEl.innerHTML = '<span class="syn-keyword">FILE</span> *fp = <span class="syn-func">fopen</span>(<span class="syn-string">"data.txt"</span>, <span class="syn-string">"' + mode + '"</span>);';
}
function drawArrow() {
const svgRect = svg.getBoundingClientRect();
const fromRect = fpBox.getBoundingClientRect();
const toRect = fileBox.getBoundingClientRect();
const startX = fromRect.right - svgRect.left;
const startY = fromRect.top + fromRect.height / 2 - svgRect.top;
const endX = toRect.left - svgRect.left - 8;
const endY = toRect.top + toRect.height / 2 - svgRect.top;
arrowPath.setAttribute('d', 'M' + startX + ',' + startY + ' L' + endX + ',' + endY);
arrowHead.setAttribute('points', endX + ',' + endY + ' ' + (endX - 9) + ',' + (endY - 6) + ' ' + (endX - 9) + ',' + (endY + 6));
}
function resetVisual() {
fpBox.className = 'fp-box';
fpBox.textContent = '?';
fileBox.classList.remove('is-active');
arrowPath.classList.remove('is-visible');
arrowHead.classList.remove('is-visible');
resultNote.className = 'result-note';
resultNote.textContent = '';
fileContent.textContent = existsToggle.checked ? ORIGINAL_CONTENT : '(no file)';
}
function run() {
const exists = existsToggle.checked;
resetVisual();
const needsExisting = (mode === 'r' || mode === 'r+');
const willFail = needsExisting && !exists;
if (willFail) {
fpBox.classList.add('is-null');
fpBox.textContent = 'NULL';
resultNote.className = 'result-note warn';
resultNote.textContent = '⚠️ data.txt doesn\u2019t exist — fopen() fails, fp = NULL.';
fileContent.textContent = '(no file)';
return;
}
// success
fpBox.classList.add('is-ok');
fpBox.textContent = 'address';
fileBox.classList.add('is-active');
drawArrow();
arrowPath.classList.add('is-visible');
arrowHead.classList.add('is-visible');
let content, note, cursorAtEnd = false;
if (mode === 'r' || mode === 'r+') {
content = ORIGINAL_CONTENT;
note = '✅ Opened — content untouched, cursor at the start.';
} else if (mode === 'w' || mode === 'w+') {
content = '';
note = exists ? '✅ Opened — existing content wiped, file is now empty.' : '✅ File didn\u2019t exist, so it was created empty.';
} else { // a or a+
content = exists ? ORIGINAL_CONTENT : '';
cursorAtEnd = true;
note = exists ? '✅ Opened — content kept, cursor jumps to the end.' : '✅ File didn\u2019t exist, so it was created — cursor at the end.';
}
fileContent.innerHTML = cursorAtEnd
? (content || '') + '<span class="file-cursor">|</span>'
: '<span class="file-cursor">|</span>' + (content || '(empty)');
resultNote.className = 'result-note ok';
resultNote.textContent = note;
}
chips.forEach(chip => {
chip.addEventListener('click', () => {
chips.forEach(c => c.classList.remove('is-active'));
chip.classList.add('is-active');
mode = chip.dataset.mode;
updateCode();
refRows.forEach(r => r.classList.toggle('is-active-row', r.dataset.mode === mode));
resetVisual();
});
});
existsToggle.addEventListener('change', resetVisual);
runBtn.addEventListener('click', run);
window.addEventListener('resize', () => { if (fpBox.classList.contains('is-ok')) drawArrow(); });
updateCode();
refRows.forEach(r => r.classList.toggle('is-active-row', r.dataset.mode === mode));
resetVisual();
})();
</script>🔴 Closing a File – fclose()
<div class="infographic-cfclose">
<style>
.infographic-cfclose {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--warn: #b45309;
--warn-soft: #fdf0dc;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
}
.infographic-cfclose[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--warn: #e0a458;
--warn-soft: #3a2c14;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-cfclose {
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1rem, 4vw, 2.25rem) 1.25rem;
}
.infographic-cfclose *, .infographic-cfclose *::before, .infographic-cfclose *::after {
box-sizing: border-box;
}
.infographic-cfclose h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.3rem, 3.5vw, 1.7rem);
margin: 1.25rem 0 0.2rem;
text-align: center;
}
.infographic-cfclose .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1.3rem; text-align: center; }
.infographic-cfclose .code-panel {
background: #1e1e2e;
color: #d4d4e0;
border-radius: 8px;
padding: 0.55rem 0.9rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
margin-bottom: 1.2rem;
text-align: center;
}
.infographic-cfclose[data-theme="dark"] .code-panel { background: #0d0d14; }
.infographic-cfclose .cp-kw { color: #c586c0; }
.infographic-cfclose .cp-fn { color: #dcdcaa; }
.infographic-cfclose .scene {
display: flex;
align-items: center;
justify-content: center;
gap: 1.4rem;
padding: 0.5rem 0 1rem;
flex-wrap: wrap;
}
.infographic-cfclose .box-wrap { text-align: center; }
.infographic-cfclose .box {
width: 5.6rem;
height: 4.6rem;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 1.3rem;
transition: border-color 0.4s, background 0.4s, opacity 0.5s;
border: 2.5px solid var(--line);
background: var(--paper-alt);
}
.infographic-cfclose .box.buffer { border-style: dashed; }
.infographic-cfclose .box.has-data { border-color: var(--accent); background: var(--accent-soft); }
.infographic-cfclose .box.is-flushed { border-color: var(--ok); background: var(--ok-soft); }
.infographic-cfclose .box.is-lost { opacity: 0.25; }
.infographic-cfclose .box-label { font-family: 'IBM Plex Mono', monospace; font-size: 0.7rem; color: var(--ink-soft); margin-top: 0.4rem; }
.infographic-cfclose .box-mini { font-family: 'IBM Plex Mono', monospace; font-size: 0.62rem; color: var(--ink-soft); margin-top: 0.1rem; min-height: 0.9rem; }
.infographic-cfclose .arrow-static { font-size: 1.2rem; color: var(--ink-soft); }
.infographic-cfclose .fp-tag {
display: inline-block;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.75rem;
font-weight: 700;
padding: 0.3rem 0.6rem;
border-radius: 8px;
border: 1px solid var(--line);
color: var(--ink-soft);
cursor: pointer;
margin-bottom: 1rem;
transition: border-color 0.3s, background 0.3s, color 0.3s;
}
.infographic-cfclose .fp-tag.is-open { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.infographic-cfclose .fp-tag.is-closed { border-color: var(--line); background: var(--paper-alt); color: var(--ink-soft); opacity: 0.7; }
.infographic-cfclose .fp-wrap { text-align: center; }
.infographic-cfclose .controls { display: flex; align-items: center; justify-content: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.8rem; }
.infographic-cfclose .ctrl-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem; font-weight: 600;
padding: 0.42rem 0.85rem;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--paper-alt);
color: var(--ink);
}
.infographic-cfclose .ctrl-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.infographic-cfclose .ctrl-btn.danger { border-color: var(--warn); color: var(--warn); }
.infographic-cfclose .ctrl-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.infographic-cfclose .ctrl-btn:hover:not(:disabled) { opacity: 0.88; }
.infographic-cfclose .note {
text-align: center;
font-size: 0.82rem;
font-weight: 600;
min-height: 1.3rem;
margin-bottom: 0.9rem;
}
.infographic-cfclose .note.ok { color: var(--ok); }
.infographic-cfclose .note.warn { color: var(--warn); }
.infographic-cfclose .takeaway {
font-size: 0.82rem; color: var(--ink-soft);
margin-top: 1.1rem; border-top: 1px solid var(--line); padding-top: 0.9rem;
}
.infographic-cfclose .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cfclose * { transition: none !important; }
}
</style>
<h1>🔴 fclose()</h1>
<p class="subhead">Writes don't reach the disk until you close the file.</p>
<div class="code-panel"><span class="cp-fn">fclose</span>(fp);</div>
<div class="fp-wrap">
<span class="fp-tag is-open" id="fp-tag">fp — open</span>
</div>
<div class="controls">
<button class="ctrl-btn primary" id="write-btn">fprintf(fp, …)</button>
</div>
<div class="scene">
<div class="box-wrap">
<div class="box buffer" id="buffer-box">🗂️</div>
<div class="box-label">buffer</div>
<div class="box-mini" id="buffer-mini"></div>
</div>
<div class="arrow-static">→</div>
<div class="box-wrap">
<div class="box" id="file-box">📄</div>
<div class="box-label">file.txt (disk)</div>
<div class="box-mini" id="file-mini"></div>
</div>
</div>
<div class="controls">
<button class="ctrl-btn" id="close-btn" disabled>fclose(fp)</button>
<button class="ctrl-btn danger" id="crash-btn" disabled>💥 crash (skip fclose)</button>
<button class="ctrl-btn" id="reset-btn">⟲ Reset</button>
</div>
<p class="note" id="scene-note"></p>
<p class="takeaway"><strong>fclose() does two things:</strong> it flushes any buffered writes out to the actual file, and it releases fp — using fp after this point is undefined behavior.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cfclose')
|| document.querySelector('.infographic-cfclose');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function $(sel) { return wrapper.querySelector(sel); }
const fpTag = $('#fp-tag');
const writeBtn = $('#write-btn');
const closeBtn = $('#close-btn');
const crashBtn = $('#crash-btn');
const resetBtn = $('#reset-btn');
const bufferBox = $('#buffer-box');
const bufferMini = $('#buffer-mini');
const fileBox = $('#file-box');
const fileMini = $('#file-mini');
const note = $('#scene-note');
let closed = false;
let bufferedText = '';
let fileText = '';
function render() {
bufferBox.classList.toggle('has-data', bufferedText.length > 0);
bufferBox.classList.remove('is-lost', 'is-flushed');
bufferMini.textContent = bufferedText ? '"' + bufferedText + '"' : '';
fileBox.classList.toggle('has-data', fileText.length > 0);
fileMini.textContent = fileText ? '"' + fileText + '"' : '(empty)';
fpTag.className = 'fp-tag ' + (closed ? 'is-closed' : 'is-open');
fpTag.textContent = closed ? 'fp — closed' : 'fp — open';
writeBtn.disabled = closed;
closeBtn.disabled = closed || bufferedText.length === 0;
crashBtn.disabled = closed || bufferedText.length === 0;
}
writeBtn.addEventListener('click', () => {
if (closed) return;
bufferedText += (bufferedText ? ' ' : '') + 'Hi';
note.className = 'note';
note.textContent = '';
render();
});
closeBtn.addEventListener('click', () => {
if (closed || !bufferedText) return;
bufferBox.classList.add('is-flushed');
fileText += (fileText ? ' ' : '') + bufferedText;
bufferedText = '';
closed = true;
note.className = 'note ok';
note.textContent = '✅ fclose() flushed the buffer — file.txt now has it for real.';
render();
});
crashBtn.addEventListener('click', () => {
if (closed || !bufferedText) return;
bufferBox.classList.add('is-lost');
bufferedText = '';
closed = true;
note.className = 'note warn';
note.textContent = '⚠️ No fclose() before the crash — that buffered data never made it to disk.';
render();
});
fpTag.addEventListener('click', () => {
if (closed) {
note.className = 'note warn';
note.textContent = '🚫 fp is already closed — using it now is undefined behavior.';
}
});
resetBtn.addEventListener('click', () => {
closed = false;
bufferedText = '';
fileText = '';
note.className = 'note';
note.textContent = '';
render();
});
render();
})();
</script>This:
Frees memory
Saves the file properly
Prevents data corruption
📖 Reading from Files
🅰️ fgetc(fp) – Read a single character
char ch = fgetc(fp);🅱️ fgets(str, size, fp) – Read a full line or string
char line[100];
fgets(line, 100, fp);🅾️ fscanf(fp, "%d %s", &num, str) – Formatted input
Like scanf, but from a file.
✅ Example:
#include <stdio.h>
int main() {
FILE *fp = fopen("input.txt", "r");
if (fp == NULL) {
printf("File could not be opened.\\n");
return 1;
}
int num;
char str[50];
fscanf(fp, "%d %s", &num, str);
printf("Read values: %d and %s\\n", num, str);
fclose(fp);
return 0;
}📝 Contents of input.txt:
100 CodeVeda<div class="infographic-cread">
<style>
.infographic-cread {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--code-bg: #1e1e2e;
--code-text: #d4d4e0;
--syn-keyword: #c586c0;
--syn-func: #dcdcaa;
--syn-string: #ce9178;
--syn-comment: #6a9955;
--warn: #b45309;
--warn-soft: #fdf0dc;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
}
.infographic-cread[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--code-bg: #0d0d14;
--code-text: #d4d4e0;
--warn: #e0a458;
--warn-soft: #3a2c14;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-cread {
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1rem, 4vw, 2.25rem) 1.25rem;
}
.infographic-cread *, .infographic-cread *::before, .infographic-cread *::after {
box-sizing: border-box;
}
.infographic-cread h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.3rem, 3.5vw, 1.7rem);
margin: 1.25rem 0 0.2rem;
text-align: center;
}
.infographic-cread .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1.1rem; text-align: center; }
.infographic-cread h2 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: 1.05rem;
margin: 0 0 0.8rem;
text-align: center;
}
.infographic-cread section { margin-bottom: 2.1rem; }
.infographic-cread section + section { border-top: 1px solid var(--line); padding-top: 1.6rem; }
.infographic-cread .chip-row { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 0.9rem; flex-wrap: wrap; }
.infographic-cread .chip {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 600;
padding: 0.4rem 0.85rem;
border-radius: 20px;
border: 1px solid var(--line);
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.infographic-cread .chip:hover { border-color: var(--accent); }
.infographic-cread .chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.infographic-cread .code-panel {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.6rem 0.9rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
line-height: 1.55;
margin-bottom: 0.9rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
text-align: center;
}
.infographic-cread .code-panel .code-line { display: block; white-space: pre; }
.infographic-cread .code-panel .code-line.is-highlight {
background: rgba(91, 141, 239, 0.22);
box-shadow: inset 3px 0 0 var(--accent);
}
.infographic-cread .syn-keyword { color: var(--syn-keyword); }
.infographic-cread .syn-func { color: var(--syn-func); }
.infographic-cread .syn-string { color: var(--syn-string); }
.infographic-cread .syn-comment { color: var(--syn-comment); }
.infographic-cread .file-strip { display: flex; gap: 0.3rem; justify-content: center; flex-wrap: wrap; margin-bottom: 0.6rem; }
.infographic-cread .file-tok {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
padding: 0.35rem 0.55rem;
border-radius: 6px;
border: 1.5px solid var(--line);
background: var(--paper-alt);
color: var(--ink-soft);
transition: border-color 0.25s, background 0.25s, color 0.25s, opacity 0.25s;
}
.infographic-cread .file-tok.is-consumed { opacity: 0.35; }
.infographic-cread .file-tok.is-current { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.infographic-cread .read-row { display: flex; align-items: center; justify-content: center; gap: 0.6rem; margin-bottom: 0.6rem; flex-wrap: wrap; }
.infographic-cread .read-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem; font-weight: 600;
padding: 0.42rem 0.9rem;
border-radius: 999px;
background: var(--accent);
color: #fff;
}
.infographic-cread .read-btn:hover { opacity: 0.88; }
.infographic-cread .read-btn:disabled { opacity: 0.4; cursor: default; }
.infographic-cread .reset-mini {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
color: var(--ink-soft);
border: 1px solid var(--line);
padding: 0.4rem 0.7rem;
border-radius: 999px;
}
.infographic-cread .result-panel {
text-align: center;
padding: 0.6rem 0.9rem;
background: var(--paper-alt);
border-radius: 8px;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
min-height: 2.3rem;
}
.infographic-cread .result-panel strong { color: var(--accent); }
.infographic-cread .takeaway {
font-size: 0.82rem; color: var(--ink-soft);
margin-top: 0.5rem;
}
.infographic-cread .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cread * { transition: none !important; }
}
</style>
<h1>📖 Reading from Files</h1>
<p class="subhead">Same file, three ways to read it.</p>
<section>
<div class="chip-row" id="reader-tabs">
<button class="chip is-active" data-fn="fgetc">fgetc()</button>
<button class="chip" data-fn="fgets">fgets()</button>
<button class="chip" data-fn="fscanf">fscanf()</button>
</div>
<div class="code-panel" id="reader-code"></div>
<div class="file-strip" id="file-strip"></div>
<div class="read-row">
<button class="read-btn" id="read-btn"></button>
<button class="reset-mini" id="reader-reset">⟲</button>
</div>
<div class="result-panel" id="reader-result">Click read to begin.</div>
</section>
<p class="takeaway"><strong>Pick your grain:</strong> fgetc reads one character, fgets reads one line, fscanf reads whatever tokens match your format string — all from the same file.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cread')
|| document.querySelector('.infographic-cread');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function $(sel) { return wrapper.querySelector(sel); }
// ================= Reader explorer =================
const readerCode = $('#reader-code');
const fileStrip = $('#file-strip');
const readBtn = $('#read-btn');
const resetBtn = $('#reader-reset');
const resultPanel = $('#reader-result');
const tabs = wrapper.querySelectorAll('#reader-tabs .chip');
const READERS = {
fgetc: {
code: '<span class="syn-keyword">char</span> ch = <span class="syn-func">fgetc</span>(fp);',
tokens: ['H', 'i', '!', '\\n'],
label: 'fgetc(fp)',
readOne: (toks, i) => 'ch = \'' + (toks[i] === '\\n' ? '\\n' : toks[i]) + '\''
},
fgets: {
code: '<span class="syn-keyword">char</span> line[100];\n<span class="syn-func">fgets</span>(line, 100, fp);',
tokens: ['CodeVeda\\n', 'Learn C\\n', 'Have fun'],
label: 'fgets(line, 100, fp)',
readOne: (toks, i) => 'line = "' + toks[i] + '"'
},
fscanf: {
code: '<span class="syn-keyword">int</span> num; <span class="syn-keyword">char</span> str[50];\n<span class="syn-func">fscanf</span>(fp, <span class="syn-string">"%d %s"</span>, &num, str);',
tokens: ['100', 'CodeVeda'],
label: 'fscanf(fp, "%d %s", ...)',
readOne: (toks, i) => 'num = ' + toks[0] + ', str = "' + toks[1] + '"',
allAtOnce: true
}
};
let mode = 'fgetc';
let pos = 0;
function renderTokens() {
const r = READERS[mode];
fileStrip.innerHTML = '';
r.tokens.forEach((tok, i) => {
const el = document.createElement('span');
el.className = 'file-tok';
if (i < pos) el.classList.add('is-consumed');
if (i === pos && pos < r.tokens.length) el.classList.add('is-current');
el.textContent = tok;
fileStrip.appendChild(el);
});
}
function renderReader() {
const r = READERS[mode];
readerCode.innerHTML = r.code;
readBtn.textContent = '▶ ' + r.label;
renderTokens();
const atEnd = pos >= r.tokens.length;
readBtn.disabled = atEnd;
if (pos === 0) resultPanel.innerHTML = 'Click read to begin.';
if (atEnd && pos > 0) resultPanel.innerHTML = 'End of file reached.';
}
readBtn.addEventListener('click', () => {
const r = READERS[mode];
if (pos >= r.tokens.length) return;
if (r.allAtOnce) {
resultPanel.innerHTML = r.readOne(r.tokens, pos);
pos = r.tokens.length;
} else {
resultPanel.innerHTML = r.readOne(r.tokens, pos);
pos++;
}
renderReader();
});
resetBtn.addEventListener('click', () => { pos = 0; renderReader(); });
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('is-active'));
tab.classList.add('is-active');
mode = tab.dataset.fn;
pos = 0;
renderReader();
});
});
renderReader();
})();
</script>✍️ Writing to Files
✏️ fputc('A', fp) – Write one character
#include <stdio.h>
int main() {
FILE *fp = fopen("char.txt", "w");
if (fp == NULL) {
printf("File could not be opened.\\n");
return 1;
}
fputc('A', fp);
fputc('\\n', fp); // newline
fclose(fp);
printf("Character written to char.txt\\n");
return 0;
}✍️ fputs("Hello", fp) – Write a string
#include <stdio.h>
int main() {
FILE *fp = fopen("string.txt", "w");
if (fp == NULL) {
printf("File could not be opened.\\n");
return 1;
}
fputs("Hello", fp);
fputs("\\nWorld!", fp);
fclose(fp);
printf("String written to string.txt\\n");
return 0;
}🧾 fprintf(fp, "Name: %s", name) – Formatted output (like printf)
#include <stdio.h>
int main() {
FILE *fp = fopen("formatted.txt", "w");
if (fp == NULL) {
printf("File could not be opened.\\n");
return 1;
}
char name[] = "CodeVeda";
int age = 21;
fprintf(fp, "Name: %s\\n", name);
fprintf(fp, "Age: %d\\n", age);
fclose(fp);
printf("Formatted data written to formatted.txt\\n");
return 0;
}<div class="infographic-cwrite">
<style>
.infographic-cwrite {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--code-bg: #1e1e2e;
--code-text: #d4d4e0;
--syn-keyword: #c586c0;
--syn-func: #dcdcaa;
--syn-string: #ce9178;
}
.infographic-cwrite[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--code-bg: #0d0d14;
--code-text: #d4d4e0;
}
.infographic-cwrite {
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1rem, 4vw, 2.25rem) 1.25rem;
}
.infographic-cwrite *, .infographic-cwrite *::before, .infographic-cwrite *::after {
box-sizing: border-box;
}
.infographic-cwrite h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.3rem, 3.5vw, 1.7rem);
margin: 1.25rem 0 0.2rem;
text-align: center;
}
.infographic-cwrite .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1.1rem; text-align: center; }
.infographic-cwrite .chip-row { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 1rem; flex-wrap: wrap; }
.infographic-cwrite .chip {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 600;
padding: 0.4rem 0.85rem;
border-radius: 20px;
border: 1px solid var(--line);
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.infographic-cwrite .chip:hover { border-color: var(--accent); }
.infographic-cwrite .chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.infographic-cwrite .tab-panel { display: none; }
.infographic-cwrite .tab-panel.is-active { display: block; }
.infographic-cwrite .code-panel {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.6rem 0.9rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
line-height: 1.55;
margin-bottom: 1.1rem;
text-align: center;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.infographic-cwrite .code-panel .code-line { display: block; white-space: pre; }
.infographic-cwrite .syn-keyword { color: var(--syn-keyword); }
.infographic-cwrite .syn-func { color: var(--syn-func); }
.infographic-cwrite .syn-string { color: var(--syn-string); }
.infographic-cwrite .write-row { display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin-bottom: 0.6rem; flex-wrap: wrap; }
.infographic-cwrite .write-row label { font-family: 'IBM Plex Mono', monospace; font-size: 0.8rem; color: var(--ink-soft); }
.infographic-cwrite .write-row input[type="text"] {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
padding: 0.32rem 0.5rem;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
width: 8rem;
}
.infographic-cwrite .write-row input.char-input { width: 3rem; text-align: center; }
.infographic-cwrite .write-row input.age-input { width: 4rem; }
.infographic-cwrite .write-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem; font-weight: 600;
padding: 0.42rem 0.85rem;
border-radius: 999px;
background: var(--accent);
color: #fff;
}
.infographic-cwrite .write-btn:hover { opacity: 0.88; }
.infographic-cwrite .mini-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.74rem;
padding: 0.4rem 0.7rem;
border-radius: 999px;
border: 1px solid var(--line);
color: var(--ink-soft);
}
.infographic-cwrite .mini-btn:hover { border-color: var(--accent); }
.infographic-cwrite .file-card {
border: 1px solid var(--line);
border-radius: 8px;
padding: 0.7rem 0.9rem;
margin-top: 0.9rem;
}
.infographic-cwrite .file-card .fc-title {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.03em;
color: var(--ink-soft);
margin-bottom: 0.4rem;
}
.infographic-cwrite .file-card .fc-body {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
color: var(--ink);
white-space: pre-wrap;
min-height: 1.4rem;
}
.infographic-cwrite .fc-cursor { color: var(--accent); font-weight: 700; }
.infographic-cwrite .takeaway {
font-size: 0.82rem; color: var(--ink-soft);
margin-top: 1.3rem; border-top: 1px solid var(--line); padding-top: 0.9rem;
}
.infographic-cwrite .takeaway strong { color: var(--ink); }
</style>
<h1>✍️ Writing to Files</h1>
<p class="subhead">Three ways to put data on disk.</p>
<div class="chip-row" id="write-tabs">
<button class="chip is-active" data-tab="fputc">fputc()</button>
<button class="chip" data-tab="fputs">fputs()</button>
<button class="chip" data-tab="fprintf">fprintf()</button>
</div>
<!-- fputc -->
<div class="tab-panel is-active" data-tab="fputc">
<div class="code-panel"><span class="syn-func">fputc</span>(<span class="syn-string">'A'</span>, fp);</div>
<div class="write-row">
<label>char</label>
<input type="text" class="char-input" id="fc-char" maxlength="1" value="A">
<button class="write-btn" id="fc-write">▶ fputc(ch, fp)</button>
</div>
<div class="write-row">
<button class="mini-btn" id="fc-newline">fputc('\n', fp)</button>
<button class="mini-btn" id="fc-reset">⟲ Reset</button>
</div>
<div class="file-card">
<div class="fc-title">char.txt</div>
<div class="fc-body" id="fc-file"><span class="fc-cursor">|</span></div>
</div>
</div>
<!-- fputs -->
<div class="tab-panel" data-tab="fputs">
<div class="code-panel">
<span class="code-line"><span class="syn-func">fputs</span>(<span class="syn-string">"Hello"</span>, fp);</span>
<span class="code-line"><span class="syn-func">fputs</span>(<span class="syn-string">"\nWorld!"</span>, fp);</span>
</div>
<div class="write-row">
<label>str</label>
<input type="text" id="fs-str" value="Hello">
<button class="write-btn" id="fs-write">▶ fputs(str, fp)</button>
</div>
<div class="write-row">
<button class="mini-btn" id="fs-quick">fputs("\nWorld!", fp)</button>
<button class="mini-btn" id="fs-reset">⟲ Reset</button>
</div>
<div class="file-card">
<div class="fc-title">string.txt</div>
<div class="fc-body" id="fs-file"><span class="fc-cursor">|</span></div>
</div>
</div>
<!-- fprintf -->
<div class="tab-panel" data-tab="fprintf">
<div class="code-panel">
<span class="code-line"><span class="syn-func">fprintf</span>(fp, <span class="syn-string">"Name: %s\n"</span>, name);</span>
<span class="code-line"><span class="syn-func">fprintf</span>(fp, <span class="syn-string">"Age: %d\n"</span>, age);</span>
</div>
<div class="write-row">
<label>name</label>
<input type="text" id="fp-name" value="CodeVeda">
<button class="mini-btn" id="fp-write-name">fprintf name</button>
</div>
<div class="write-row">
<label>age</label>
<input type="text" class="age-input" id="fp-age" value="21">
<button class="mini-btn" id="fp-write-age">fprintf age</button>
</div>
<div class="write-row">
<button class="mini-btn" id="fp-reset">⟲ Reset</button>
</div>
<div class="file-card">
<div class="fc-title">formatted.txt</div>
<div class="fc-body" id="fp-file"><span class="fc-cursor">|</span></div>
</div>
</div>
<p class="takeaway" id="write-takeaway"></p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cwrite')
|| document.querySelector('.infographic-cwrite');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function $(sel) { return wrapper.querySelector(sel); }
function esc(s) { return s.replace(/&/g, '&').replace(/</g, '<'); }
function renderFile(el, content) {
el.innerHTML = esc(content) + '<span class="fc-cursor">|</span>';
}
// ---- tabs ----
const tabs = wrapper.querySelectorAll('#write-tabs .chip');
const panels = wrapper.querySelectorAll('.tab-panel');
const takeaway = $('#write-takeaway');
const TAKEAWAY = {
fputc: '<strong>Every call adds one character.</strong> Write \'A\' then \'\\n\' and char.txt ends up holding exactly "A" on its own line.',
fputs: '<strong>fputs writes a whole string</strong> in one call — no automatic newline, so you add \'\\n\' yourself when you want one.',
fprintf: '<strong>fprintf is printf for files</strong> — same format specifiers, same %s / %d, just aimed at fp instead of the screen.'
};
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('is-active'));
tab.classList.add('is-active');
panels.forEach(p => p.classList.toggle('is-active', p.dataset.tab === tab.dataset.tab));
takeaway.innerHTML = TAKEAWAY[tab.dataset.tab];
});
});
takeaway.innerHTML = TAKEAWAY.fputc;
// ---- fputc ----
let fcContent = '';
const fcFile = $('#fc-file');
$('#fc-write').addEventListener('click', () => {
const ch = $('#fc-char').value.slice(0, 1);
if (!ch) return;
fcContent += ch;
renderFile(fcFile, fcContent);
});
$('#fc-newline').addEventListener('click', () => {
fcContent += '\n';
renderFile(fcFile, fcContent);
});
$('#fc-reset').addEventListener('click', () => {
fcContent = '';
renderFile(fcFile, fcContent);
});
// ---- fputs ----
let fsContent = '';
const fsFile = $('#fs-file');
function interpretEscapes(s) { return s.replace(/\\n/g, '\n'); }
$('#fs-write').addEventListener('click', () => {
const str = $('#fs-str').value;
if (!str) return;
fsContent += interpretEscapes(str);
renderFile(fsFile, fsContent);
});
$('#fs-quick').addEventListener('click', () => {
fsContent += '\nWorld!';
renderFile(fsFile, fsContent);
});
$('#fs-reset').addEventListener('click', () => {
fsContent = '';
renderFile(fsFile, fsContent);
});
// ---- fprintf ----
let fpContent = '';
const fpFile = $('#fp-file');
$('#fp-write-name').addEventListener('click', () => {
const name = $('#fp-name').value;
fpContent += 'Name: ' + name + '\n';
renderFile(fpFile, fpContent);
});
$('#fp-write-age').addEventListener('click', () => {
const age = $('#fp-age').value;
fpContent += 'Age: ' + age + '\n';
renderFile(fpFile, fpContent);
});
$('#fp-reset').addEventListener('click', () => {
fpContent = '';
renderFile(fpFile, fpContent);
});
renderFile(fcFile, fcContent);
renderFile(fsFile, fsContent);
renderFile(fpFile, fpContent);
})();
</script>📍 Positioning in File (Advanced)
To move around inside the file (like skipping lines or jumping back):
Function | Use |
|---|---|
| Move to a position |
| Get current position |
| Go to the start |
⚠️ Always Check for Errors
Before using the file, check if it opened properly:
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("Error opening file.\\n");
}fopen() returns NULL if file doesn’t exist or can’t be opened.
🧠 Summary
Real Life | C File Handling |
|---|---|
Opening notebook |
|
Writing in notebook |
|
Reading a sentence |
|
Closing notebook |
|