DDS
DDS

Reputation: 27

How to get total sum of values from input file?

Hello can someone tell me how can i get only value of total sum of notes (1x20 ;10x50 ,100x50 = total 111 notes) from input text file?

I try something with line.find() but when i have two/three-digit number like 10 x 50 USD ,100 x 50 USD it gave me error:

Unhandled exception exception: std::out_of_range at memory location 0x005FDB1C

Here is the code

int total=0;
string str2="USD";
std::ifstream file("input.txt");
            if (file.is_open()) {
                std::string line;
                while (getline(file, line)) {

                    if (line.find(str2) != string::npos) {
                        cout << line.substr((line.find("USD")-7))<< '\n';
                        int d = stoi(line.substr((line.find(" x")- 1)));
                        total = total + d;
                        cout << "Total sum: " << total;
                            }
                }
                file.close();
            }

Input file:


===============================

DATE: 20190929  TIME: 13:55:24

MY ID: mypc

===============================

 Client: 1234
DATE: 2019.09.17 TIME: 14:19:14

0 x 0 USD

1 x 20 USD


 Client: 4567
DATE: 2019.09.17 TIME: 14:21:33

0 x 0 USD

10 x 50 USD

 Client: 8910
DATE: 2019.09.17 TIME: 14:34:25

0 x 0 USD

100 x 50 USD

===============================

Upvotes: 1

Views: 192

Answers (3)

anatolyg
anatolyg

Reputation: 28251

Here is how you could implement the parsing using C++ regular expressions:

#include <regex>
...

        while (std::getline(file, line)) {
            std::smatch match;
            if (std::regex_match(line, match, std::regex("\\s*([0-9]+) x ([0-9]+) USD\\s*"))) {
                int number_of_notes = std::stoi(match[1]);
                int value = std::stoi(match[2]);
                total += number_of_notes * value;
                std::cout << "Total sum: "<< total << std::endl;
            }
        }

Here match is an object which stores the result of the parsing.

A breakdown of the regular expression:

  • \s* - allows leading and trailing spaces
  • ([0-9]+) - captures (using parentheses) a sequence of 1 or more digits into the match object
  • Spaces, x, and USD - requires the input to have these; only those input lines which have this text will match the regex

If you use regular expressions, it might be easier to adapt your code if you ever decide to upgrade your input file format - ideally, you would only need to change the regex, not the code.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409196

One possible way is to save the position you get from line.find(str2) in a variable. Then create a substring from the beginning of the line to that position:

auto usd_pos = line.find(str2);
if (usd_pos != std::string::npos)
{
    auto value_string = line.substr(0, usd_pos);
    ...
}

Once you got the substring with the numbers in it, put it into an input string stream (std::istringstream) and read the integers and the 'x' from that stream:

int first_value, second_value;
char dummy_x_char;

std::istringstream stream_with_values(value_string);
stream_with_values >> first_value >> dummy_x_char >> second_value;

Upvotes: 1

Clonk
Clonk

Reputation: 2070

Parsing string using absolute position is error prone. When you have token separated value (especially if the tokens are whitespace) that you need to store into typed variable, it is easier to use streams (such as std::stringstream).

This is one way to do it :

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

int main() {
    int total=0;
    std::string str2="USD";
    std::ifstream file("input.txt");
    if (file.is_open()) {
        std::string line;
        while (std::getline(file, line)) {
            if (line.find(str2) != std::string::npos) {
                std::stringstream ss(line);
                int number_of_notes, value;
                std::string operatorX, USD_string;
                ss >> number_of_notes>> operatorX >> value >> USD_string;
                total += number_of_notes;
                std::cout << "Total sum: "<< total << std::endl;
            }
        }
        file.close();
    }
}

Upvotes: 1

Related Questions