skip to Main Content

I have a problem with input and output. My code in Visual Studio don’t throw any errors, but the platform, where i try to send the code, throw Runtime Error.

terminate called after throwing an instance of ‘std::invalid_argument’
what(): stoi

Input:

5
[05:00 a.m.]: Server is started
[05:00 a.m.]: Rescan initialized
[01:13 p.m.]: Request processed
[01:10 p.m.]: Request processed
[11:40 p.m.]: Rescan completed
Output: 2

My Code:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm>
#include <fstream>
#include <typeinfo>

using namespace std;

int main() {
    ifstream fin;
    ofstream fout;
    fin.open("input.txt");
    string s;
    int n, hh, mm;
    fin >> n;
    vector<string>A;
    for (int i = 0; i < n+1; i++) {
        string s;
        getline(fin, s);
        if (s != "") A.push_back(s);
    }
    fin.close();
    int days = 1;
    vector<int>t;
    for (int i = 0; i < A.size(); i++) {
        hh = stoi(A[i].substr(1, 2));
        mm = stoi(A[i].substr(4, 2));
        string x = A[i].substr(7, 1);
        int time = hh * 60 + mm;
        if (time == 0) days++;
        if (x == "p" && time != 720) time += 720;
        t.push_back(time);
    }
    for (int i = 1; i < t.size(); i++) {
        if (t[i] < t[i - 1]) days++;
    }
    fout.open("output.txt");
    fout << days;
    fout.close();
}

Idk when stoi accept the wrong param.

2

Answers


  1. Chosen as BEST ANSWER

    Work for me, thanks @Someprogrammerdude

        getline(fin, s);
        n = stoi(s);
        for (int i = 0; i < n + 1 && std::getline(fin, s); i++) {
            A.push_back(s);
        }
    

  2. Since you’re apparently trying to parse a time, it’s probably easiest to use std::get_time. Ideally, you’d get them to change the format ever so slightly, so your input would look like this:

    [05:00 am]: Server is started
    [05:00 am]: Rescan initialized
    [01:13 pm]: Request processed
    [01:10 pm]: Request processed
    [11:40 pm]: Rescan completed
    

    With this input, you can do something like this:

        std::string line;
        while (std::getline(input, line)) {
    
            std::stringstream buffer(line);        
            std::tm timestamp;
    
            buffer >> std::get_time(&timestamp, "[%I:%M %p]: ");
    
            std::cout << "Timestamp: " << std::put_time(&timestamp, "%Rn");
        }
    

    If you can’t get them to change the format, perhaps you can use something like sed to do the job. Lacking even that, you can write a little function to "fix" it, something like this:

    void fix_ampm(std::string &s) {
        std::map<std::string, std::string> fixes {
            { "a.m.", "am"},
            { "p.m.", "pm"}
        };
    
        for (auto const &[find, rep] : fixes) {
            auto pos = s.find(find);
            if (pos != std::string::npos) {
                s.replace(pos, find.size(), rep);
            }
        }
    }
    

    In theory, you can write a locale facet to parse the required format, but unless you’re going to use this specific format quite a bit, that’s probably more trouble than it’s worth.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search