This problem involves parsing a continuous string to identify and sum numerical values, handling both integers and decimals, then printing the result with proper thousand separators and rounding.
Input Parsing
Since the input contains no spaces, the entire sequence can be read into a character buffer using standard input functions.
char buffer[1005];
scanf("%s", buffer);
We iterate through the buffer. Any non-digit character acts as a delimiter and should be ignored unless it is a decimal point.
if (buffer[idx] < '0' || buffer[idx] > '9') continue;
When a digit is found, we start accumulating the number. We also need to detect if a decimal point exists and count the digits following it to determine if the value represents cents (two decimal places).
int total = 0, frac_count = 0;
bool has_point = false;
while (idx < length && (buffer[idx] >= '0' && buffer[idx] <= '9' || buffer[idx] == '.')) {
if (buffer[idx] == '.') {
has_point = true;
frac_count = 0;
idx++;
continue;
}
total = total * 10 + (buffer[idx] - '0');
frac_count++;
idx++;
}
After extracting the sequence, we determine how to add it to the sum. If a decimal point was present and exactly two digits followed it, we treat the extracted integer as a monetary value in cents.
if (has_point && frac_count == 2) {
sum += (double)total / 100.0;
} else {
sum += total;
}
Output Formatting
To print the result, we separate the integer and decimal parts. We add a small epsilon (0.005) before truncating to handle stendard rounding rules for the hundredths place.
int integer_part = (int)sum;
int decimal_part = (int)((sum - integer_part + 0.005) * 100.0);
We store the digits of the integer part in reverse order to facilitate inserting thousand separators (dots).
int digits[15], digit_count = 0;
while (integer_part > 0) {
digits[++digit_count] = integer_part % 10;
integer_part /= 10;
}
We then print the digits. A dot is inserted every three digits from the right, ensuring we do not print a trailing separator.
for (int i = digit_count; i >= 1; i--) {
printf("%d", digits[i]);
if ((i - 1) % 3 == 0 && i != 1) {
putchar('.');
}
}
If the sum is less then 1, we must explicitly print a leading zero.
if (sum < 1) {
putchar('0');
}
Finally, we print the decimal portion. If the decimal part is a single digit (less than 10), we prepend a zero to maintain the format (e.g., .05 instead of .5).
if (decimal_part >= 10) {
printf(".%d\n", decimal_part);
} else if (decimal_part > 0) {
printf(".0%d\n", decimal_part);
}
Complete Implementation
#include <cstdio>
#include <cstring>
using namespace std;
char buffer[1005];
int main() {
scanf("%s", buffer);
int length = strlen(buffer);
double sum = 0.0;
for (int idx = 0; idx < length; idx++) {
if (buffer[idx] < '0' || buffer[idx] > '9') continue;
int value = 0, digit_cnt = 0;
bool point_found = false;
while (idx < length && (buffer[idx] >= '0' && buffer[idx] <= '9' || buffer[idx] == '.')) {
if (buffer[idx] == '.') {
point_found = true;
digit_cnt = 0;
idx++;
continue;
}
value = value * 10 + (buffer[idx] - '0');
digit_cnt++;
idx++;
}
if (point_found && digit_cnt == 2) {
sum += (double)value / 100.0;
} else {
sum += value;
}
}
int int_part = (int)sum;
int dec_part = (int)((sum - int_part + 0.005) * 100.0);
int rev_digits[15], rev_cnt = 0;
while (int_part > 0) {
rev_digits[++rev_cnt] = int_part % 10;
int_part /= 10;
}
for (int i = rev_cnt; i >= 1; i--) {
printf("%d", rev_digits[i]);
if ((i - 1) % 3 == 0 && i != 1) putchar('.');
}
if (sum < 1) putchar('0');
if (dec_part >= 10) printf(".%d\n", dec_part);
else if (dec_part > 0) printf(".0%d\n", dec_part);
return 0;
}