-3

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;
    }
}
hnefatl
  • 5,860
  • 2
  • 27
  • 49
Vincent Lynn
  • 31
  • 1
  • 6
  • The text file should like this 123, 123, 431, -> next line 5123, 12312 25316, 64234, 1231, 124123 – Vincent Lynn Jan 14 '18 at 12:03
  • 1
    This code doesn't try to solve the problem you mentioned in your question, so you should include a more relevant [mcve]. That said, you need to seek from the beginning to the end before calling `tellg` to get the file length (see [here](https://stackoverflow.com/questions/2409504/using-c-filestreams-fstream-how-can-you-determine-the-size-of-a-file) for various methods). – hnefatl Jan 14 '18 at 12:09
  • 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 Jan 14 '18 at 12:13
  • 1
    No, you can't `seekg` relative to lines - the file is just seen as a 1D stream of `char`s. You can use [`getline`](http://en.cppreference.com/w/cpp/string/basic_string/getline) to read an entire line at a time, though. – hnefatl Jan 14 '18 at 12:15
  • Voted to close because the code doesn't even contain the vectors you are talking about. – Christian Hackl Jan 14 '18 at 12:21
  • To start with you could look up how to read the file **line by line** https://stackoverflow.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: https://stackoverflow.com/search?q=%5Bc%2B%2B%5D+split+string – Galik Jan 14 '18 at 13:13

1 Answers1

0

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;
    }
}
Mindaugas Bernatavičius
  • 3,757
  • 4
  • 31
  • 58
  • 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 Jan 14 '18 at 23:19
  • 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 Jan 15 '18 at 05:46
  • I figured it out. :) Thanks for your help. Now, i am working on inserting vector element into linked list. – Vincent Lynn Jan 15 '18 at 07:58