Lerul Ler
Lerul Ler

Reputation: 339

Reading words from file and storing them in a vector c++

void print(vector<const char*> v) {
    for (vector<const char*>::const_iterator i = v.begin(); i != v.end(); ++i)
        cout << *i << ' ';
    cout << endl;
}
int main()
{
    vector<const char*> v;
    FILE *infile;
    infile = fopen("Text.txt", "r");
    char buffer[100];
    while ((fgets(buffer, 100, infile) != NULL)) {
        if (buffer[strlen(buffer) - 1] == '\n')
            buffer[strlen(buffer) - 1] = '\0';
        v.push_back((const char*)buffer);
        printf("%s\n", buffer);
    }
    fclose(infile);
    print(v);
return 0;

}

So this is what I have so far. At the printf (in the while loop), the words from the file are printed correctly. But the function print (which prints the elements of the vector) shows me only the last word repeated by the number of words from the file. For example, let's say I have this in my file:

apple
banana
orange

The print function will print:

orange
orange
orange

Edit: So I managed to get this to work. I made a list of "buffers" and it's working fine now. Thanks everyone for your help!

Upvotes: 1

Views: 1202

Answers (2)

kamikaze
kamikaze

Reputation: 1579

Since an actual answer has already posted, your print() function could use some improvements:

void print(vector<const char*> const & v) {
    for (auto const chp : v) {
        cout << chp << ' ';
    }
    cout << '\n';
}

This version takes a reference instead of copying the whole vector. And because the vector isn't changed by print() it's const.

Also if you want to iterate over all elements of a container you don't have to manage the iterators manually.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726919

The problem is that you are calling push_back on the same array buffer, each time storing the same pointer to its initial element in the vector.

This means, among other things, that no matter what you put into buffer, before or after calling push_back, the vector elements are going to point to it. In your case the result is that you see the last element that you have read, but if you wrote to buffer after reading the file, the vector would show that new value.

In order to solve this problem you need to push back copies of the buffer, instead of pushing the buffer itself. The preferred approach in C++ would be switching away from vector<const char*> to vector<string>, because strings make the copying and resource management much easier for you.

If you must use pointers, make vector store non-const pointers; otherwise you wouldn't be able to call delete on them. Instead of pushing back buffer allocate strlen(buffer)+1 chars with new[], and strcpy the buffer into it before calling push_back.

Upvotes: 3

Related Questions