Messy invoice lines
A document scanner exports invoice lines as quantity price, both whole numbers of pence. The scanner is unreliable: some lines are missing a field, some contain text where a number should be, some are blank, and occasionally a negative number slips in. A line is valid only if it has exactly two fields that both parse as integers greater than or equal to zero.
Read lines until the input ends. Add quantity * price for every valid line and count every invalid line. Print the total and the number of rejected lines.
Input
Zero or more lines. A valid line is two non-negative integers separated by a single space. Any other line, including a blank line, is invalid.
Output
Two lines: Total: t (the sum of quantity times price over the valid lines) and Rejected: r (the number of invalid lines).
Example 1
Input
3 250 2 x 4 100 7 1 -5
Output
Total: 1150 Rejected: 4
Only 3 250 (750) and 4 100 (400) are valid. The other four lines are rejected: text, blank, a missing field and a negative price.
Constraints
- At most 100 lines
- On a valid line 0 <= quantity <= 1000 and 0 <= price <= 100000
- The total can exceed the range of a 32-bit int
Hints
Hint 1 of 3
Console.ReadLine() returns null once the input is exhausted; a while loop on that is the standard read-to-end pattern.
Hint 2 of 3
int.Parse throws a FormatException when the text is not a number. Catch that specific exception type and count the line as rejected.
Hint 3 of 3
A blank line splits into one empty field, so checking parts.Length != 2 rejects blank and short lines before any parsing. Multiply into a long so the total cannot overflow.
Solution
Show a reference solution and explanation
long total = 0;
int rejected = 0;
string? line;
while ((line = Console.ReadLine()) != null)
{
string[] parts = line.Split(' ');
if (parts.Length != 2)
{
rejected++;
continue;
}
try
{
int quantity = int.Parse(parts[0]);
int price = int.Parse(parts[1]);
if (quantity < 0 || price < 0)
{
rejected++;
continue;
}
total += (long)quantity * price;
}
catch (FormatException)
{
rejected++;
}
}
Console.WriteLine($"Total: {total}");
Console.WriteLine($"Rejected: {rejected}");
Why it works
The program separates the two kinds of failure. A wrong number of fields is a structural problem you can detect with a plain if, so no exception is needed. Text that will not parse is only discovered inside int.Parse, and that is where try/catch (FormatException) earns its place: the exception carries the failure out of the parse and into a handler that records it. Catching FormatException rather than a bare Exception keeps genuine bugs visible. The cast (long)quantity * price matters: 25 lines of 1000 * 100000 sum to 2,500,000,000, past the 2,147,483,647 limit of int, and integer overflow in C# silently wraps by default rather than throwing. int.TryParse is the exception-free alternative when bad input is expected rather than exceptional.