Files Streams

By the end of this lesson you'll be able to write data to a file, read it back line by line or token by token, choose the right file mode, and parse text in memory with std::stringstream — the same stream skills power files, the console, and strings in C++.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Think of a stream as a conveyor belt for characters. cout is a belt running out to your screen; cin is a belt running in from the keyboard. A file stream is the exact same belt — it just connects to a file on disk instead. Because every belt works the same way, the << ("push onto the belt") and >> ("take off the belt") operators you already know for the console work unchanged on files and on strings. Learn one, and you've learned all three.

1. Writing a File with ofstream

std::ofstream (output file stream) opens a file for writing . You give it a filename, then push data onto it with << — exactly like cout . The golden rule: always check is_open() first, because a wrong path or a read-only folder fails silently otherwise. Read this worked example, then run it locally and open scores.txt to see the result.

2. Reading a File with ifstream

std::ifstream (input file stream) opens a file for reading . You have two tools: std::getline(in, line) grabs a whole line at a time, while in >> value reads one whitespace-separated token and converts its type for you. Both return the stream itself , which becomes "false" at end-of-file (EOF) — so they're perfect loop conditions that stop on their own.

3. File Modes: app and binary

By default ofstream overwrites a file. Pass a mode flag as the second argument to change that. std::ios::app means append — new writes go to the end and existing content is kept (ideal for log files). std::ios::binary writes raw bytes with no text formatting, which you need for .write() / .read() on structs. std::fstream opens a file for reading and writing at once.

Heads-up: binary files are not portable across machines — endianness and struct padding differ between architectures. For data you'll share, prefer a text format (CSV, JSON) or a serialization library.

4. Parsing in Memory with stringstream

A std::stringstream is a stream backed by a std::string instead of a file. std::istringstream lets you read a string with getline and >> (perfect for splitting a CSV line into fields); std::ostringstream lets you build a string with << and pull the result out with .str() . Because it's all in memory, it runs anywhere — so the exercises below work right here in the editor.

Your turn. The program below is almost complete — fill in the blanks marked ___ using the hints, then run it.

One more. This time you'll read numbers with >> and build a report string with ostringstream . Fill in the two blanks:

No blanks this time — just a brief and an outline. You'll parse a comma-separated line entirely in memory with istringstream , so it runs right here. Build it, run it, and check your output against the example in the comments.

Practice quiz

Which stream type opens a file for WRITING?

  • std::ifstream
  • std::istringstream
  • std::ofstream
  • std::cin

Answer: std::ofstream. std::ofstream (output file stream) opens a file for writing; ifstream is for reading.

What should you always do right after opening a file stream?

  • Check is_open() before reading or writing
  • Call .flush()
  • Call .seekg(0)
  • Set ios::binary mode

Answer: Check is_open() before reading or writing. A wrong path or read-only folder fails silently, so always guard with is_open() first.

When should you use getline() instead of >> ?

  • When you want one whitespace-separated token
  • getline() and >> are identical
  • Only when reading numbers
  • When you want a whole line, including the spaces inside it

Answer: When you want a whole line, including the spaces inside it. >> reads one token (a word or number); getline() grabs a whole line, and with a delimiter it splits CSV fields.

What does the file mode std::ios::app do?

  • Opens the file in binary mode
  • Appends new writes to the end, keeping existing content
  • Truncates the file to empty
  • Opens the file for reading only

Answer: Appends new writes to the end, keeping existing content. ios::app appends: writes go to the end and existing content is kept — ideal for log files.

Why is looping on while (!in.eof()) a common bug?

  • EOF is set AFTER a failed read, so it processes the last line twice
  • eof() does not exist on ifstream
  • It is too slow
  • It only works in binary mode

Answer: EOF is set AFTER a failed read, so it processes the last line twice. Loop on the read itself — while (getline(in, line)) or while (in >> x) — so EOF stops you cleanly.

What does std::ios::binary change?

  • It compresses the file
  • It makes the file read-only
  • It turns off text translation so bytes are written exactly as-is
  • It appends to the file

Answer: It turns off text translation so bytes are written exactly as-is. Binary mode skips newline translation; you need it for .write()/.read() on structs and other non-text data.

How do you read up to the next comma in a CSV field with getline?

  • getline(iss, field, comma)
  • getline(iss, field, ',')
  • iss >> field >> ','
  • getline(iss.comma(), field)

Answer: getline(iss, field, ','). getline(stream, target, ',') reads characters up to the next comma delimiter.

How do you get the finished string out of a std::ostringstream named report?

  • report.get()
  • report.string()
  • report >> result
  • report.str()

Answer: report.str(). You build text with << then call .str() to pull the result out of the ostringstream.

Why do the 'Your Turn' exercises in this lesson use std::stringstream instead of real files?

  • stringstream is faster than files
  • Online compilers often have no writable filesystem, but stringstream works entirely in memory
  • Files cannot hold text
  • stringstream is required by C++20

Answer: Online compilers often have no writable filesystem, but stringstream works entirely in memory. Sandboxed online compilers may lack a writable filesystem, so in-memory stringstream runs anywhere.

Do you strictly need to call .close() on a file stream?

  • Yes, or the file is corrupted
  • Only for ifstream, never ofstream
  • No — RAII closes it at scope end, but .close() flushes immediately and frees the file for others
  • Only in binary mode

Answer: No — RAII closes it at scope end, but .close() flushes immediately and frees the file for others. File streams are RAII, so the destructor closes them; calling close() explicitly flushes the buffer and releases the file now.