C++ Module 14
Input/output, files, formatting and time interview questions
Interview questions on input/output, files, formatting and time: warm-ups, then what each harder question tests and how a good answer starts.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher
When would you use std::format_to or std::format_to_n instead of std::format?
-
Fresher
What is the difference between fail() and bad() on an input stream?
Answered in the lesson C++ stream states: failbit, eofbit and badbit
-
Fresher
What is the difference between opening a file with std::ios::app and with std::ios::ate?
Answered in the lesson File handling in C++: ifstream and ofstream
-
Fresher
What is the difference between std::filesystem::canonical and std::filesystem::weakly_canonical?
Answered in the lesson std::filesystem: paths, directories and metadata
-
Fresher
What is the difference between std::chrono::steady_clock and std::chrono::system_clock?
Answered in the lesson C++ <chrono>: durations, clocks and dates
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Mid to senior
A logging library builds every line with std::format and then writes it to a file. Under load, profiling shows memory allocation among the top costs. How do you remove the allocations without giving up checked format strings, and how do you prove that they are gone?
- What it tests
- Knowing which formatting calls allocate, writing into reused or fixed buffers, and measuring allocations rather than guessing.
- First step
- Count first: replace the global operator new in a test build with one that counts calls, format a known number of lines, and print the count. That number is the baseline every change must beat, and it shows whether the strings, not the file writes, are the cost.
- Follow-ups
-
- Where should the reused buffer live when several threads log at once?
- What happens to a line longer than the fixed buffer?
- Why might the counter report different numbers in optimised builds?
From the lesson std::format and std::print in depth
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A CSV export writes prices with std::format("{}", price). The finance team's importer rejects some rows, and you find values such as 1e+05 in the file. Explain why std::format wrote that, and what you would write for each column instead.
- What it tests
- The shortest round-trip rule for floating point, choosing presentation types and precisions, and keeping money out of floating point.
- First step
- Reproduce it with the exact values from the rejected rows and print them with {}, {:.2f} and {:.17g}. The pattern in which values change form tells you the rule, and it is a rule of the default presentation, not a bug in the data.
- Follow-ups
-
- Why does 120000.0 print as 120000 but 100000.0 as 1e+05?
- Is {:.2f} enough for amounts of money?
- What changes if the program runs with a locale that uses a decimal comma?
From the lesson std::format and std::print in depth
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A function sums the numbers in a file with while (!in.eof()) { in >> x; sum += x; }. It passes its unit tests but reports a wrong total for some real files. Explain what goes wrong, fix it, and say how you would find similar loops in a large code base.
- What it tests
- When eofbit is set, why a failed read leaves the variable alone, testing the read itself, and turning a bug pattern into a search or a lint rule.
- First step
- Write the loop out for a file holding 10 20 30 followed by a line break, and track the stream state and the variable after every read. Then compare it with the same numbers without the final line break, which is what hand-written test strings often look like.
- Follow-ups
-
- Why does the test written by hand not catch it?
- What is the correct loop, and what does it do at a bad value?
- How would you find every such loop automatically?
From the lesson C++ stream states: failbit, eofbit and badbit
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A command-line ordering tool reads a quantity with unsigned qty; std::cin >> qty; and checks the stream before using it. A user types -5. What does the program see, and how would you read counts so that such input is rejected?
- What it tests
- How stream extraction converts signed text into unsigned types, why a passing state check is not validation, and reading into a wide signed type with an explicit range check.
- First step
- Do not answer from memory: print the value and the stream's flags after the read, with every standard library the tool ships with. Then write down the valid range of a quantity, which is a business rule, and design the read around checking that range.
- Follow-ups
-
- What does the same read do with 4294967296?
- Why is reading into a signed type and converting afterwards safer?
- How does std::from_chars behave on the same inputs?
From the lesson C++ stream states: failbit, eofbit and badbit
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A sensor-data parser reads doubles with operator>>. Its tests pass on Linux with GCC, but on macOS with Apple clang it accepts some lines the Linux build rejects, and extreme values come out different. How do you find the cause and make the parser behave the same on both?
- What it tests
- Implementation differences between standard libraries in numeric extraction, what the standard fixes and what it leaves open, and designing input validation that does not depend on them.
- First step
- Collect the lines that behave differently and run them through a tiny program that prints, for each library, the stored value, the state flags and what is left unread. Differences in out-of-range values and unusual number syntax are the usual suspects.
- Follow-ups
-
- Which library is right about hexadecimal input such as 0x1p3?
- How should the parser treat a value that overflows a double?
- What would you put in the test suite so that this cannot come back?
From the lesson C++ stream states: failbit, eofbit and badbit
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A desktop app saves settings with std::ofstream out(path); out << settings;. Some users report that after a crash or a power cut their settings file is empty or cut short. Explain how that happens and design a save that never loses the old settings.
- What it tests
- What opening for writing does to an existing file, buffering and when data reaches the disk, atomic replacement by rename, and the role of fsync.
- First step
- Write down every moment between opening the file and the process ending, and ask what the file holds on disk at each one. The interesting moment is the very first: opening for output already changes the file.
- Follow-ups
-
- Why is rename the safe step, and where does that guarantee come from?
- What does a power cut add to the problem that a crash does not?
- What should happen to the temporary file when saving fails?
From the lesson File handling in C++: ifstream and ofstream
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A service writes its audit log through an std::ofstream and never checks the stream. When the disk filled up, the log silently stopped and nobody noticed for days. Where do write errors show up with file streams, and how would you make the logger notice and report them?
- What it tests
- Buffering in stream objects, which calls can report write failures, why destructors cannot, and designing error reporting for a component that must not fail silently.
- First step
- List where bytes wait on their way to the disk: the stream's buffer, the operating system and the device. A write error can only be noticed when bytes move from one to the next, so find the calls in the logger that make them move.
- Follow-ups
-
- How can you reproduce a full disk in a test?
- Is errno a reliable way to learn the reason?
- What should the service do once the log cannot be written?
From the lesson File handling in C++: ifstream and ofstream
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A file-copy function written with std::ifstream and std::ofstream copies images correctly on Linux and macOS, but on Windows the copies are corrupted and slightly larger. Explain why, fix it, and say how you would prove that a copy is exact.
- What it tests
- Text and binary mode, which byte values text mode changes on Windows, reading with read() and gcount(), and verifying copies with sizes and checksums.
- First step
- Compare the original and the copy byte by byte in a hex viewer and find the first difference. The bytes around it, and the fact that the copy is larger, point straight at the mode the files were opened in.
- Follow-ups
-
- Why does the same code work on Linux and macOS?
- Why can the copy also be shorter than the original?
- How would you copy a file of several gigabytes?
From the lesson File handling in C++: ifstream and ofstream
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A small web server serves files from a public folder. It joins the requested path to the folder with operator/ and accepts the result if its text starts with the folder's path. A security test shows that files outside the folder can be read. Show how, and write the check you would use.
- What it tests
- How operator/ treats absolute paths, why text prefixes fail, resolving links and dot segments, comparing paths by component, and testing a security check.
- First step
- Write requests that should be refused and run them through the existing check before reading any code: dot segments, an absolute path, a sibling folder whose name starts with the public folder's name, and a link inside the folder. Each one that passes shows a separate hole.
- Follow-ups
-
- Why is canonical() alone not enough for files that do not exist?
- What remains even after the check is correct?
- How do you keep the check from regressing?
From the lesson std::filesystem: paths, directories and metadata
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A cleanup tool deletes cache files older than 30 days with a recursive_directory_iterator. It works on developers' machines but crashes on some servers with an uncaught std::filesystem::filesystem_error, and on one machine it never finishes. What would you check, and how would you make the walk robust?
- What it tests
- Error reporting of directory iterators, permission problems, links that loop, the error_code forms, and designing a long-running walk that keeps going and reports what it skipped.
- First step
- Read the exception's code and paths, not just its message: they name the folder and the system error. Then list what server trees contain that developer laptops rarely do, such as folders owned by other users and links to other parts of the disk.
- Follow-ups
-
- What do skip_permission_denied and follow_directory_symlink change?
- Why can deleting files while walking be dangerous?
- What should the tool print at the end?
From the lesson std::filesystem: paths, directories and metadata
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
A colleague's code checks std::filesystem::exists(path) before writing a new file, to avoid overwriting one. Another colleague calls it a race. Explain the race, show the consequences in a program that runs with more rights than its users, and give the safe ways to create or open such a file.
- What it tests
- Time-of-check to time-of-use races, link attacks in shared folders, exclusive creation, and opening first then checking the opened file.
- First step
- Put two timelines side by side: the program's check and open, and another process acting on the same path between them. Then ask what the other process could put at that path, and what the program would do with it.
- Follow-ups
-
- What does std::ios::noreplace guarantee, and what not?
- How do openat and O_NOFOLLOW help on POSIX systems?
- When is a check before opening still useful?
From the lesson std::filesystem: paths, directories and metadata
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Fresher to mid
A subscription service bills customers every month on the day they signed up. Customers who signed up on day 31, or on a leap day, report missing or doubled bills. Design the date calculation with the C++20 calendar types and say how you would test it.
- What it tests
- Month arithmetic on invalid dates, choosing and documenting a policy, computing from the start date instead of the previous one, and test cases for month ends and leap years.
- First step
- Before code, agree the rule with the people who own billing: what is the billing day in a month that does not have the sign-up day? Then compute a few months for a sign-up on day 31 by hand and see what adding one month at a time does compared with adding n months to the start.
- Follow-ups
-
- What does year_month_day + months{1} produce for day 31, and what does converting it to sys_days do?
- Why must the nth bill be computed from the sign-up date?
- Which test cases would you write?
From the lesson C++ <chrono>: durations, clocks and dates
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A job scheduler stores jobs as local times such as 02:30 every day in the user's time zone. Twice a year, users in some zones report a job that did not run or ran twice. Explain the cause with std::chrono, and design how the scheduler should store and compute run times.
- What it tests
- Local times that do not exist or happen twice, zoned_time and its exceptions, choose::earliest and choose::latest, and storing instants in UTC with the zone's name.
- First step
- Take one zone with daylight saving time and the two nights a year its clocks change, and list every local time between 01:00 and 04:00 on those nights with its UTC instant. The gap and the overlap explain both reports at once.
- Follow-ups
-
- What does zoned_time do with a local time that does not exist?
- Which policy would you choose for skipped and repeated times?
- What changes for a zone such as Asia/Kolkata?
From the lesson C++ <chrono>: durations, clocks and dates
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A benchmark harness times each run with std::chrono::high_resolution_clock. On a build server, a few results are far too long and one is negative. What could cause that, and how would you write timing code you can trust?
- What it tests
- Which clock high_resolution_clock really is in each library, steady and unsteady clocks, and measuring short code with repetitions, warm-up and the right statistic.
- First step
- Check what high_resolution_clock is on that toolchain with a static_assert or by printing is_steady and comparing the type with steady_clock and system_clock. A negative interval can only come from a clock that went back.
- Follow-ups
-
- Why is high_resolution_clock a poor choice in portable code?
- How many repetitions and which statistic would you report?
- How do you stop the compiler from removing the code you are timing?
From the lesson C++ <chrono>: durations, clocks and dates
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 2 minutes
-
Mid to senior
A service validates every incoming order id with std::regex_match(id, std::regex("[A-Z]{3}-\\d{5}")) inside its request handler, and profiling shows the check among the top costs. What is expensive here, and what would you change, step by step?
- What it tests
- The cost of constructing a std::regex, its run-time matching cost against hand-written checks, sharing a const regex between threads, and measuring each step.
- First step
- Separate the two costs before changing anything: time building the regex alone and matching with a regex built once, on the real distribution of ids. The handler pays for both on every request, and the numbers decide which change comes first.
- Follow-ups
-
- Is a static const std::regex safe to share between threads?
- When is a hand-written check worth it?
- Which alternative libraries would you consider, and why?
From the lesson Regular expressions with std::regex
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
A form accepts a description that is validated with std::regex("^(\\w+\\s?)+$"). A penetration test makes one server thread busy for minutes with a short request. Explain the attack, how it behaves with different standard libraries, and how you would fix the validation and protect the service.
- What it tests
- Catastrophic backtracking, why nested quantifiers explode, the differing behaviour of standard library engines, rewriting patterns, linear-time engines, and limits at the service boundary.
- First step
- Reproduce it locally with growing inputs that almost match, for example words followed by a character the pattern does not allow, and time each size. Exponential growth with input length identifies backtracking at once.
- Follow-ups
-
- Why does the pattern give the engine so many ways to fail?
- How would you rewrite it?
- What would you add at the service level in case another such pattern slips in?
From the lesson Regular expressions with std::regex
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A command-line tool runs fine on Linux with GCC, but on macOS built with Apple clang it sometimes terminates with an uncaught std::regex_error while scanning text, although the pattern compiled without error. What is happening, and how should the tool handle it?
- What it tests
- Errors that std::regex can raise while matching, implementation limits in libc++, catching regex_error around searches, and choosing patterns and engines that behave the same on every platform.
- First step
- Catch the exception in a debug build and print e.code() and the input that triggered it. If the code is error_complexity, the pattern is backtracking on that input, and the difference between the platforms is how each library handles that.
- Follow-ups
-
- Why does the GCC build not throw?
- Is catching the exception enough?
- How would you test the tool on both platforms?
From the lesson Regular expressions with std::regex
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 2 minutes