C++ Delivery Manifest Project
Parse a complete two-field record into a typed result and commit output only after all checks succeed.
Your brief
Define a deliberately small manifest format: a nonempty stop token without commas, then one comma, then a parcel count from zero through one thousand. The numeric field uses exact decimal conversion with no whitespace. This is not general CSV: quoted fields, embedded separators and multiline records require a format-aware parser. Return an optional owned record so failed parsing cannot leave a partially updated caller object. Validate framing and the entire number before constructing the accepted result.
Run it locally
Use a C++20 compiler and matching standard library in a separate lab folder. The command uses c++; substitute g++, clang++ or zig c++ for your toolchain. C++ does not currently run in Bhylu’s browser playground. Apache, PHP and MySQL are not needed.
c++ -std=c++20 -Wall -Wextra -Wpedantic -Werror manifest-project.cpp -o lessonOn Windows use -o lesson.exe and run .\lesson.exe in PowerShell. On Unix-like systems run ./lesson. Thread examples may need -pthread on your platform.
Download the complete C++ source. Run file labs in a private empty directory, away from existing reports.
Worked solution
Show the worked solution
#include <iostream>
#include <string>
#include <string_view>
#include <optional>
#include <charconv>
#include <system_error>
struct StopRecord { std::string name; int parcels; };
std::optional<StopRecord> parse_stop(std::string_view line) {
auto comma = line.find(',');
if (comma == std::string_view::npos || comma == 0 || comma + 1 == line.size()) { return std::nullopt; }
auto text = line.substr(comma + 1);
int count{};
auto [end, error] = std::from_chars(text.data(), text.data() + text.size(), count);
if (error != std::errc{} || end != text.data() + text.size() || count < 0 || count > 1000) { return std::nullopt; }
return StopRecord{std::string{line.substr(0, comma)}, count};
}
int main() {
auto record = parse_stop("Quay,12");
if (!record) { return 1; }
std::cout << record->name << ": " << record->parcels << '\n';
std::cout << "Junk accepted: " << parse_stop("Quay,12x").has_value() << '\n';
}
Expected result
Quay: 12
Junk accepted: 0
The returned record owns its name instead of retaining a view into the caller input. A second comma in the numeric suffix fails complete conversion, while an empty name or missing count fails framing. For real files, impose an input-size limit before or during reading; this parser does not make an unbounded transport safe. Add a richer error result when a user needs to know which field was rejected.
Extend and test
Test missing separators, an empty name, missing count, negative and excessive counts, extra commas and oversized integer text. State the grammar before adding spaces or quoted names.
Consult the WG21 C++ working group and the C++ Core Guidelines for language references and design guidance. Check the selected standard version and your implementation’s library support.