1

I have a file that contains, numbers(ints) and words both, I want to read only the integers, Please ignore the macros if they are annoying, However I only need to have the integers but I have to be sure to also read the strings and then disregard them What do I have to modify here:

#include <iostream>
#include <vector>
#include <cmath>
#include <fstream>
using namespace std;
  
int main(){
    FastIO;
    ifstream fin("input.txt",ios::in);
    
    int minsal =10000000;
    int num;
    cout<<minsal;
    fin.close();
    ofstream fout("output.txt",ios::out);
    fout.close();
    
    return 0;
}

An example file could be :

Vineel Phatak, 520, Amkart, NOBODY
Ajay Joshi, 250, Amkart, Vineel Phatak
Abhishek Chauhan, 120, Amkart, Ajay Joshi
Jayesh Godse, 500, Airflix, NOBODY
Vijaya Mundada, 60, Amkart, Abhishek Chauhan
Shital Tuteja, 45, Airflix, Jayesh Godse
Rajan Gawli, 700, Amkart, Vineel Phatak
Sheila Rodrigues, 35, Amkart, Vineel Phatak
Zeba Khan, 300, Airflix, Jayesh Godse
Chaitali Sood, 100, Airflix, Zeba Khan

Pawan Nirpal
  • 319
  • 1
  • 5
  • 13
  • 3
    All those type-aliases and macros, please don't to that. It doesn't make the code "faster", and only makes it harder to read and understand it. Just please don't use competition sites (where such habits tends to be taught) as learning or teaching resources, as all they teach is such bad habits. Get [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) and take a few classes to learn *first*, then use such sites for fun and "brain training". – Some programmer dude Oct 31 '20 at 03:53
  • Honestly I just want to extract numbers from a file, I know this isn't convention but, I'd appreciate if you were to solve the problem – Pawan Nirpal Oct 31 '20 at 03:59
  • 1
    At least please try to make some attempt yourself. What have you tried? What problem do you have with your attempt? Is it the file-reading? Parsing the lines? Storing the data? Also please take some time to refresh [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Oct 31 '20 at 04:01
  • [Handy reading](https://stackoverflow.com/a/7868998/4581301). Start there. When you get to parsing the line, make sure you are familiar with `std::getline`'s third parameter. – user4581301 Oct 31 '20 at 04:06
  • 1
    Read all data from the file as a string (say, one line at a time). Examine the string, and identify what is in it. If there is an integral value, extract it and (optionally) remove that data from the string. If there is other data in the string, either copy it to other variables (e.g. strings that can be passed to other code) or discard. – Peter Oct 31 '20 at 04:51
  • 1
    After reading the line as a `std::string`, you can use [std::basic_string::find_first_of](https://en.cppreference.com/w/cpp/string/basic_string/find_first_of) to locate the first digit in each string (and if you want to find multiple sequences of digits in the same string, pay attention to the `size_type pos` parameter). You can then use, e.g. [std::stoi](https://en.cppreference.com/w/cpp/string/basic_string/stol) to convert the string of digits to an integer value. – David C. Rankin Oct 31 '20 at 08:06

2 Answers2

1

you need to fetch your input file line by line and then in each line get the number from it , this is an example to how get one or more number from line using regex :

#include <iostream>
#include <regex>

using namespace std;

int main() {
    int x;
    string s = "aaa 123 zefdz";
    smatch sm;
    regex r = regex("\\d+");
    regex_search(s, sm, r);
    for (string s : sm) {
        x = atoi(s.c_str());
        cout << "x : " << x;
    }
}

in this case result will be :

x : 123
aziz k'h
  • 743
  • 2
  • 10
1

You can read the values from the text file into a vector of strings. From there you can use the standard library and its algorithms to extract integers from strings. In this particular solution, I choose to use the <regex> library only to assist in pattern matching of characters. The use of <regex> does not actually extract the values out of the string nor does it convert it, it simply checks to see if a digit exists... This will not work for every use case... for example, if a string contains: "abc123def456", this particular implementation will return an integer value of 123456. You can modify this to fit your particular needs. You can do searches for regular expressions to see how you can pattern match and look for specific characters or sequences of characters within a given string. This is only to illustrate how one can use the library to provide such functionality.

#include <fstream>
#include <iostream>
#include <optional>
#include <regex>
// #include <sstream> // not used in this implementation
#include <string>
#include <vector>

std::vector<std::string> readFromFile(const char* filename) {
    std::fstream file(filename, std::ios::in); 
    std::vector<string> contents;
    std::string line;
    if ( file.is_open() ) {
        while ( getline(file, line) )
            contents.push_back(line);
        file.close();
    }
    return contents;
}

static const std::regex digits("([0-9])");

bool matches(const std::string& s, const std::regex& regex ) {
    std::smatch base_match;
    return std::regex_match(s, base_match, regex);
}

int parseString( const std::string& data ) {
    std::string temp;
    for (auto& c : data) {
        if (matches(std::string{c}, digits))
            temp.push_back(c);
    }
    return std::stoi(temp);
}

int main() {
    std::vector<std::string> fileContents = readFromFile("sample.txt");
    std::vector<int> extractedData;
    for (auto& s : fileContents)
        extractedData.push_back(parseString(s));
    for (auto& i : extractedData)
        std::cout << i << ' ';
    std::cout << '\n';

    // This is to demonstrate that care needs to be taken!!!
    const std::string garbage{ "Hello 123 World456!" };
    auto res = parseString(garbage);
    std::cout << res << '\n';

    return 0;
}

With the example data set that you provided, I was able to print this to the console as a result as well as the result from the garbage string...

520 250 120 500 60 45 700 35 300 100
123456

There are other ways to solve and tackle this problem, many will choose to use <sstream> with either std::stringstream or std::istringstream as they can perform similar operations without using regular expressions.

Francis Cugler
  • 7,462
  • 1
  • 24
  • 44
  • Thanks this worked, I suppose c++ std lib could have just added a function that does exactly this, I mean after all this is a quite common operation. – Pawan Nirpal Nov 01 '20 at 10:27
  • 1
    @PawanNirpal Maybe in time, well see more. Things like this need to be submitted to the Standard Committee for approval, and that can take time. I think they leave it as it is because many want the flexibility to customize their parsing algorithms to fit their own particular needs. – Francis Cugler Nov 01 '20 at 19:20