I need a help with my code. I am trying to read txt file and then I want to put each line into difference vector. For example, I have a file like this.

123, 123, 431, 5123, 12312
25316, 64234, 1231, 124123

I want to put the first line to the first vector. 123|123|431| and the second vector. 25316|64234|

I already tried seekg. But, it doesn't work. What is the best way to do it? Later, I will use these vector with Linkedlist.

Here is my code.

#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

int main()
{
    string fname;
    cout << "Please enter file name!" << endl;
    cin >> fname;

    string line;
    fstream myfile;
    myfile.open(fname);

    if (myfile.is_open())
    {
        myfile.seekg(0, ios_base::end);
        int length = myfile.tellg();

        cout << length <<endl;
    }
    else
    {
        cout << "Unable to open your file!" << endl;
    }
}
upvote
  flag
The text file should like this 123, 123, 431, -> next line 5123, 12312 25316, 64234, 1231, 124123 – Vincent Lynn
1 upvote
  flag
This code doesn't try to solve the problem you mentioned in your question, so you should include a more relevant Minimal, Complete, and Verifiable example. That said, you need to seek from the beginning to the end before calling tellg to get the file length (see here for various methods). – hnefatl
upvote
  flag
I already tried that out. I got the file length. But I only want the first line, second line or thrid line. For example, the first line length is 33. so, is that possible to set position x to position y? the only option i saw is ios_base::begin, ios_base::cur and ios_base:cur end. Thanks – Vincent Lynn
1 upvote
  flag
No, you can't seekg relative to lines - the file is just seen as a 1D stream of chars. You can use getline to read an entire line at a time, though. – hnefatl
upvote
  flag
Voted to close because the code doesn't even contain the vectors you are talking about. – Christian Hackl
upvote
  flag
To start with you could look up how to read the file line by line //allinonescript.com/search?q=%5Bc%2B%2B%5D+line+by+line Then you could look up how to split each line to put the elements into a vector: //allinonescript.com/search?q=%5Bc%2B%2B%5D+split+string – Galik

1 Answers 11

up vote 0 down vote accepted

First, on handling the lines separately:

  • As explained by others you should not use std::basic_istream::seekg(). It works with absolute positions in the streambuf and would require way more code for your use-case than necessary (you would have to find newlines in the stream, split and so on).

  • Use getline().

Example:

if (myfile.is_open())
{
    short line_num = 1;
    for (std::string line; std::getline(myfile, line); ) {
        cout << "Line number: " << line_num << " Value: " << line << std::endl;
        line_num++;
    }
}

Output:

mindaugasb@c_cpp:~/workspace/StackOverflow/ReadingAFileLineByLine $ ./r2v.exe 
Please enter file name!
f
Line number: 1 Value: 123, 123, 431, 5123, 12312
Line number: 2 Value: 25316, 64234, 1231, 124123

Second on pushing the lines, item at a time, to a vector:

I will assume there will be two vectors, for the two lines in the input file. If there are more lines, you will need to create more vectors, possibly by implementing a function that will accept as string (obtained from the input file) and return a vector in the form you want it. Example:

vector<string> line2Vec(string line)
{
    char * tokens;
    char * line_chararr = const_cast< char *>(line.c_str());   
    tokens = strtok(line_chararr, ", ");
    vector<string> vs;

    while (tokens != NULL)
    {
        vs.push_back(tokens);
        tokens = strtok (NULL, ", ");
    }

    return vs;
}

Attention - I do not say that this is perfect Cpp code or a perfect solution to your problem. However it is A solution to how I understood the problem based on what was written. Here is the full version to play around with:

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <sstream>
#include <vector>
#include <string.h>

using namespace std;

vector<string> line2Vec(string line)
{
    cout << line << endl;

    char * tokens;
    char * line_chararr = const_cast< char *>(line.c_str());   
    tokens = strtok(line_chararr, ", ");

    vector<string> vs;

    while (tokens != NULL)
    {
        vs.push_back(tokens);
        tokens = strtok (NULL, ", ");
    }

    return vs;
}

int main()
{
    string fname;
    cout << "Please enter file name!" << endl;
    cin >> fname;

    fstream  myfile;
    myfile.open(fname);

    if (myfile.is_open())
    {
        for (std::string line; std::getline(myfile, line); ) {
            line2Vec(line);
        }
    }
    else
    {
        cout << "Unable to open your file!" << endl;
    }
}
upvote
  flag
Thanks for helping. The code above put every line into one vector, vs. Can you give me an example, how do I put each line into difference vector. or should i just split this vector into smaller vectors as I know the indices of vectors – Vincent Lynn
upvote
  flag
The code above will add values for each line into a vector, 1 vector per line (you only need to assign the result of the line2Vec(line); call). I would gladly help if I knew what you meant by a "difference vector"? Is it a vector that contains only elements that are only present in one of the vectors? – Mindaugas Bernatavičius
upvote
  flag
I figured it out. :) Thanks for your help. Now, i am working on inserting vector element into linked list. – Vincent Lynn

Not the answer you're looking for? Browse other questions tagged or ask your own question.