-1

I am trying to do file read by column. Main function is that my file should be show one of columns all values. I am trying to do it with vectors.

void search(){
const int COLUMNS = 4;

    vector< vector <int> > data;

    string filename = "bla.txt";

    ifstream ifile(filename.c_str());


    if (ifile.is_open()) {
        int num;

        vector <int> numbers_in_line;

        while (ifile >> num) {
            numbers_in_line.push_back(num);

            if (numbers_in_line.size() == COLUMNS) {
                data.push_back(numbers_in_line);
                numbers_in_line.clear();
            }
        }
    }
    else {
        cerr << "There was an error opening the input file!\n";
        exit(1);
    }

    //now get the column from the 2d vector:
    vector <int> column;
    int col = 2;//example: the 2nd column

    for (int i = 0; i < data.size(); ++i) {
        column.push_back(data[i][col - 1]);
        cout << column[i] << endl;
    }

    ifile.close();
}

my file looks like:

John 1990 1.90 1
Peter 1980 1.88 0
...

This code compiles, but I am not getting any value shown in console. When I try to debug last line it wont get cached, so I guess they do nothing?

NotsoPr0
  • 101
  • 1
  • 4
  • 10
  • You intend for `John` and `Peter` to be stored inside your `vector ` instead the fail bit of ifstream is set, you go out of loop. Then since `data.size()` is equal to 0, nothing is outputed. – user Mar 05 '17 at 14:50
  • how to make it multi type vector? – NotsoPr0 Mar 05 '17 at 14:56
  • @NotsoPr0: That's a completely different question. You should therefore ask a new question here on SO or search existing ones. Hint: something like `boost::any` may be helpful. – Christian Hackl Mar 05 '17 at 14:58

2 Answers2

2
while (ifile >> num) {

The loop is never entered because num is an int and the first element of the input line is John, which cannot be interpreted as an int, so ifile is set to an error state and the loop condition is immediately false.

The clean fix is to first read the entire line with std::getline and then tokenise the resulting std::string, for example with an std::istringstream.

Individual std::string tokens resulting from that tokenisation can then be converted to appropriate types with functions like std::stoi.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
1

Do step by step and make sure each step is correct.

  1. Read each line, then print out to make sure you are doing it correctly.
  2. You need to split each line. After this step, you will have John, 1990 etc as strings. My favorite split method
  3. Now convert 2-4th columns into integers.

There are good solutions for each step that you can easily find.

Community
  • 1
  • 1
smttsp
  • 4,011
  • 3
  • 33
  • 62
  • I am little bit confused, how to make that 3 step. How to split to columns. Maybe you could show me some hints? – NotsoPr0 Mar 05 '17 at 14:59
  • 1
    Why are you so intent on incorrectly marking your list as *code*? – Christian Hackl Mar 05 '17 at 15:01
  • @NotsoPr0 Just copy paste that code in the link. Then call the function as `vector myvec = split(line, ' ')`. This will split with space and you will have a `vector< strings>` which you will need to convert to `int` – smttsp Mar 05 '17 at 15:15
  • Sooner or later you need to learn vectors because they are extremely useful. It is similar to arrays but with many more functionalities. I bet you can learn most of it in an hour – smttsp Mar 05 '17 at 15:23