1

This code:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;

const int max_applications_num = 1000;

enum { AUTHOR, TITLE, VENUE, YEAR, PRESENTATION };

vector<vector<string> > database;

void Tokenize(string line, vector<string> &tokens, string delimiters = "\t ") {
string token = "";
string OneCharString = " ";
for (size_t i = 0; i < line.size(); i++)
    if (find(delimiters.begin(), delimiters.end(), line[i]) !=
        delimiters.end()) // line[i] is one of the delimiter characters
    {
        if (token != "")
            tokens.push_back(token);
        token = "";
    } else {
        OneCharString[0] = line[i];
        token += OneCharString;
    }

if (token != "")
    tokens.push_back(token);
}

void SaveApplication(const vector<string> &tokens) {
    database.emplace_back(tokens.begin()+1, tokens.end());
}

void remove_application(size_t pos) {
    assert(pos < database.size());
    database.erase(database.begin()+pos);
}

int year_of(vector<string> const &record) { return stoi(record[YEAR]); }
int year_of(int i) { return year_of(database.at(i)); }

void sort() {
    for (size_t j = 0; j <= database.size() - 1; j++) {

    vector<string> tmp = database.at(j);

    int tmp_year = year_of(tmp);

    int i = j - 1;
    while (i > -1 and year_of(i) > tmp_year) {
        database.at(i + 1) = database.at(i);
        i = i - 1;
    }

    database.at(i + 1) = tmp;
    }
}

void print() {
    for (size_t i = 0; i < database.size(); i++) {
    cout 
        << database.at(i)[AUTHOR] << "\t"
        << database.at(i)[TITLE]  << "\t"
        << database.at(i)[VENUE]  << "\t"
        << database.at(i)[YEAR]   << "\t"
        << database.at(i)[PRESENTATION] 
        << endl;
}
cout << "\n" << endl;
}

void ExecuteCommands(const char *fname) {
ifstream inf;
inf.open(fname);

string line;
while (getline(inf, line).good()) {
    vector<string> tokens;
    Tokenize(line, tokens, "\t ");
    if (tokens.size() == 0)
        continue;

    if (tokens[0].compare("save_application") == 0)
        SaveApplication(tokens);

    else if (tokens[0].compare("remove_application") == 0)
        remove_application(atoi(tokens[1].c_str()));

    else if (tokens[0].compare("sort") == 0)
        sort();

    else if (tokens[0].compare("print") == 0)
        print();
}

inf.close();
}

int main(int argc, char **argv) {
if (argc != 2) {
    cout << "usage: executable.o command.txt\n";
    return 1;
}

ExecuteCommands(argv[1]);
}

With this input:

save_application "authors_list1"    "title1" "conference1"  2016    "poster"

save_application "authors_list3"    "title3" "conference2"  2010    "oral"

save_application "authors_list2"    "title2" "journal1" 2015    "none"
print
sort
print
remove_application 0
print

Should print:

"authors_list1" "title1"    "conference1"   2016    "poster"
"authors_list3" "title3"    "conference2"   2010    "oral"
"authors_list2" "title2"    "journal1"  2015    "none"


"authors_list3" "title3"    "conference2"   2010    "oral"
"authors_list2" "title2"    "journal1"  2015    "none"
"authors_list1" "title1"    "conference1"   2016    "poster"


"authors_list2" "title2"    "journal1"  2015    "none"
"authors_list1" "title1"    "conference1"   2016    "poster"

However, it gives these errors when compiled:

error: ‘class std::vector<std::vector<std::__cxx11::basic_string<char> > >’ has no member named ‘emplace_back’ database.emplace_back(tokens.begin()+1, tokens.end());

error: ‘stoi’ was not declared in this scope int year_of(vector<string> const &record) { return stoi(record[YEAR]); 

I am wondering why this occurs. For this program, we are not allowed to use classes or structs. Just the program given to us. It was to see how easy classes and structs make programming and how hard it is to actually program without them.

J.Khelly
  • 29
  • 5
  • I would think the most common cause for the compiler not knowing about `emplace_back` is not compiling with C++11, as `emplace_back` was only added from C++11. Are you compiling with C++11 or later? – Tas Oct 03 '17 at 04:20
  • You're probably not using a "modern" C++11 or later compiler, or not using the right compiler options to use C++11 or later. – davidbak Oct 03 '17 at 04:20
  • oh okay, I am using terminal on linux ubuntu 16.04 LTS. – J.Khelly Oct 03 '17 at 04:30
  • Check [this](http://coliru.stacked-crooked.com/a/42cbfc9573d64ab3) – Passer By Oct 03 '17 at 04:37
  • @J.Khelly please share your g++ command and g++ version. I think you have to use -std=C++11 flag during compilation. – Naseef Chowdhury Oct 03 '17 at 06:10
  • @J.Khelly If this is for learning, I would want to know why use `emplace_back` and not `push_back` both available in a `vector` with `push_back` available in c++03/98. – Samer Tufail Oct 03 '17 at 09:28
  • @SamerTufail emplace_back is more efficient because it can construct in-place. That's also why it was added in c++11. – sehe Oct 03 '17 at 09:29
  • @sehe I know what it does, I was implying the OP be aware of why use one over the other. – Samer Tufail Oct 03 '17 at 09:30
  • @SamerTufail Best to tell him, instead of asking, then. Also, remember to link to background like http://en.cppreference.com/w/cpp/container/vector/emplace_back or https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back – sehe Oct 03 '17 at 09:31
  • @sehe I will keep that in mind thanks, you already provided a good enough answer and the comments cover most of the OP's question this was more of an addendum. – Samer Tufail Oct 03 '17 at 09:34

1 Answers1

0

Indeed, that's because you donot enable c++11 mode (or your compiler doesn't have it). Luckily for you, I have already posted the c++03 version in the comment.

You compiled it wrong. The beauty of online compilers is that you can see exactly how to compile/use it (in this case, c++11 was enough and two tiny tweaks make it c++03 compatible) – sehe 2 hours ago

sehe
  • 374,641
  • 47
  • 450
  • 633