C++ vector storage

my vector is not recording any data from my text file

the text file contains 106,187 words but for testing purposes i'm using the below set:
bleeping
damned.
adj

blemishless
Without blemish; spotless.
adj

blendous
Pertaining to consisting of or containing blende.
adj

abaca
The Manila-hemp plant (Musa textilis); also its fiber. See Manila hemp under Manila.
n

abacinate
To blind by a red-hot metal plate held before the eyes.
v

abacination
The act of abacinating.
n

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  #include <iostream>
#include <fstream>
#include <string>
#include <vector>


using namespace std;

class Files {
private:
    string word;
    string definition;
    string type;
    string blank;
    vector<string>words;
    vector<string>definitions;
    vector<string>types;
public:
    void read();
    //void intro();
    void display(vector <string>& words);
};
void Files::display(vector <string> & words) {
   
        std::cout << "The vector elements are : ";

        for (int i = 0; i < words.size(); i++)
            cout <<"running"<< words.at(i) << ' ';
    
    
}
void Files::read()
{
    Files d;
    int i = 0;
    string  e, t;
    ifstream out("Text.txt");
    string array[]{ d.word,d.definition,d.type,d.blank };
    vector<string>words;

    
    do
    {
        (getline(out, d.word, '\n'));
        words.push_back(word); 
        getline(out, d.definition, '\n');
        definitions.push_back(definition);
        getline(out, d.type, '\n');
        types.push_back(type);
        getline(out, d.blank, '\n');

        i++;
        cout << "number of line " << i << ' ' << d.word << endl;
    } while (!out.eof());
   
    display(words);

}


int main()
{
    Files d;
    //intro();

    d.read();
    //d.display();
}


Please help
Here's a demo how to read the file properly.
Please note that there is a error checking for brevity.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <fstream>
#include <string>
#include <vector>


using namespace std;

class Files {
private:
    vector<string>words;
    vector<string>definitions;
    vector<string>types;
public:
    void read();
    //void intro();
    void display();
};
void Files::display()
{
		for (size_t i = 0; i < words.size(); ++i)
		{
			cout << "Word      : " << words[i] << '\n';
			cout << "Definition: " << definitions[i] << '\n';
			cout << "Type      : " << types[i] << '\n';
			cout << '\n';
		}    
}
void Files::read()
{
	ifstream src("Text.txt");
	if (!src)
	{
		perror("File error: ");
		return;
	}
	string word, definition,type;
	while(getline(src, word))
	{
		words.push_back(word);
		
		getline(src, definition);
		definitions.push_back(definition);
		
		getline(src, type);
		types.push_back(type);
		
		src.ignore(255, '\n'); // skip empty line
	}
}


int main()
{
    Files d;
    //intro();

    d.read();
    d.display();
}

Output:

Word      : bleeping
Definition: damned.
Type      : adj

Word      : blemishless
Definition: Without blemish; spotless.
Type      : adj

Word      : blendous
Definition: Pertaining to consisting of or containing blende.
Type      : adj

Word      : abaca
Definition: The Manila-hemp plant (Musa textilis); also its fiber. See Manila hemp under Manila.
Type      : n

Word      : abacinate
Definition: To blind by a red-hot metal plate held before the eyes.
Type      : v

Word      : abacination
Definition: The act of abacinating.
Type      : n

Last edited on
Hello nakash,

Just looking at the code I see a couple of problems.

First come up with better names than a single letter. This will help you in the future.

On line 63 you define an object of the class. Then on line 34 you define a new object of the class. Here line 34 becomes a local variable to the function which overshadows the variable defined in "main". This may work , but when the function ends all the local variables are destroyed and anything you have stored in those variables is lost.

By defining the class object in "main" you will always have access to it and when you call the functions the information read or displayed will still be there.

Your do/while loop in the read function is a problem. } while (!out.eof());. This is not going to work the way that you are thinking. By the time the condition becomes false you will have processed one extra record.

Consider
1
2
3
4
5
while (getline(out, d.word, '\n'))
{
    words.push_back(word);

    // rest of code... 

This way when the read fails, or sets "eof" the while loop is skipped and the rest of the code will come out correctly.

Line 53 would have to move outside of the while loop to print the correct results.

I will have to get it loaded and test it to see if there are any other problems.

Andy
Runs OK, see my suggested changes. Some room for improvement but what you have is workable and you might want to stick with your own.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <fstream>
#include <string>
#include <vector>


using namespace std;

class Files {
private:
    string word;
    string definition;
    string type;
    string blank;
    
    vector<string>words;
    vector<string>definitions;
    vector<string>types;
public:
    void read();
    //void intro();
    void display(vector<string>& );
};

void Files::display(vector<string> &x) {
    
    std::cout << "The vector elements are : ";
    
    for (int i = 0; i < x.size(); i++)
    cout <<"running "<< x.at(i) << '\n'; // <--
    
    
}
void Files::read()
{
    Files d;
    int i = 0;
    string  e, t;
    ifstream out("dictionary.txt");
    string array[]{ d.word,d.definition,d.type,d.blank };
    vector<string>words;
    
    
    do
    {
        getline(out, word);
        words.push_back(word);
        getline(out, definition, '\n');
        definitions.push_back(definition);
        getline(out, type, '\n');
        types.push_back(type);
        getline(out, blank, '\n');
        
        i++;
        cout << "number of line " << i << ' ' << d.word << endl;
    } while (!out.eof());
    
    display(words);
    display(definitions); // <--
    display(types); // <--
    
}


int main()
{
    Files d;
    //intro();
    
    d.read();
    //d.display();
}
number of line 1 
number of line 2 
number of line 3 
number of line 4 
number of line 5 
number of line 6 
The vector elements are : running bleeping
running blemishless
running blendous
running abaca
running abacinate
running abacination
The vector elements are : running damned.
running Without blemish; spotless.
running Pertaining to consisting of or containing blende.
running The Manila-hemp plant (Musa textilis); also its fiber. See Manila hemp under Manila.
running To blind by a red-hot metal plate held before the eyes.
running The act of abacinating.
The vector elements are : running adj
running adj
running adj
running n
running v
running n
Program ended with exit code: 0
This is a framework of how you could make it simpler/cleaner still using <vector>'s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

struct Entry
{
    string word;
    string definition;
    string type;
    
    void print()
    { cout << word << ' ' << definition << ' ' << type << '\n'; }
};

class Dictionary
{
private:
    vector<Entry> store;
    string file;
public:
    Dictionary(string aFile) { file = aFile; }
    
    void read();
    void display();
};

void Dictionary::display()
{
    std::cout << "The vector elements are:\n";
    
    for (int i = 0; i < store.size(); i++)
    {
        store[i].print();
        cout << '\n';
    }
}

void Dictionary::read()
{
    ifstream out(file);
    std::string dummy;
    
    Entry temp;
    
    while(
          getline(out, temp.word, '\n') and
          getline(out, temp.definition, '\n') and
          getline(out, temp.type, '\n') and
          getline(out, dummy, '\n')
          )
    {
        store.push_back(temp);
    }
    out.close();
}

int main()
{
    Dictionary my_dictionary("dictionary.txt");
    my_dictionary.read();
    my_dictionary.display();
}


The vector elements are:
bleeping damned. adj

blemishless Without blemish; spotless. adj

blendous Pertaining to consisting of or containing blende. adj

abaca The Manila-hemp plant (Musa textilis); also its fiber. See Manila hemp under Manila. n

abacinate To blind by a red-hot metal plate held before the eyes. v

abacination The act of abacinating. n

Program ended with exit code: 0
EDIT: .txt file sensitive to dummy line on final return. This relies on automation associated with this file when it is created.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
using namespace std;


string tolower( string word )
{
   for ( char &c : word ) c = tolower( c );
   return word;
}


struct Item
{
   string word;
   string definition;
   string type;
};

istream & operator >> ( istream &in, Item &item )
{
   getline( in >> ws, item.word ) && getline( in, item.definition ) && getline( in, item.type );
   return in;
}

ostream & operator << ( ostream &out, const Item &item )
{
   return out << item.word << '\n' << item.definition << '\n' << item.type << '\n';
}


using Dictionary = vector<Item>;


int main()
{
   Dictionary dict;
   ifstream in( "dictionary.txt" );
   for ( Item item; in >> item; ) dict.push_back( item );

   sort( dict.begin(), dict.end(), []( Item &a, Item &b ){ return tolower( a.word ) < tolower( b.word ); } );

   for ( const Item &item : dict ) cout << item << '\n';
}


abaca
The Manila-hemp plant (Musa textilis); also its fiber. See Manila hemp under Manila.
n

abacinate
To blind by a red-hot metal plate held before the eyes.
v

abacination
The act of abacinating.
n

bleeping
damned.
adj

blemishless
Without blemish; spotless.
adj

blendous
Pertaining to consisting of or containing blende.
adj

Last edited on
Hello nakash,

Now that I have had a chance to test the program. I found that you have a similar problem with the read function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

void Files::read()
{
    //Files d;  // <--- Local variable that overshadows what is defined in "main".
    int i = 0;
    string word;
    string definition;
    string type;
    string blank;
    //vector<string>words;  // <--- Local variable that overshadows the class variable.

    ifstream inFile("Text.txt");

    if (!inFile)
    {
        perror("\n\n     File error");

        return;
    }

Lines 4 and 10 create local variables that are destroyed when the function looses scope. So when you do words.push_back(word); this is to the local variable and not the class variable. The variables "definitions" and "types" both store their values in the class vectors.

I also moved the 4 strings from the class to the function where they are used. there is no need to define them in the class which only holds the last value read.

As Thomas1965 demonstrated in his line 38 and as I did
1
2
3
4
5
6
7
8
9
10
11
12
13
14
while (getline(inFile, word))
{
    words.push_back(word);

    getline(inFile, definition);
    definitions.push_back(definition);

    getline(inFile, type);
    types.push_back(type);

    getline(inFile, blank);

    i++;
}

This will allow you to read any file of any size. As long as the format of the file is the same.

If you want a little more you could use
while (getline(inFile, word) && getline(inFile, definition) && getline(inFile, type) && getline(inFile, blank)). This way if any one of those fail to read or set the "eof" bit the while loop will fail. That would leave the ".push_back"s and "i++" inside the while loop.

If you choose to use the "perror" in the if statement this is all you need because "perror" will add the ": " before the message that it adds. So
     File error: No such file or directory
would be your output.

Now once the read works properly I did this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Files::display()
{
    std::cout << "The vector elements are:\n\n";

    for (size_t i = 0; i < words.size(); i++)
    {
        //cout << "running" << words.at(i) << ' ';

        std::cout
            << words[i] << '\n'
            << definitions[i] << '\n'
            << types[i] << "\n\n";
    }
}

Since all 3 vectors should be the same size or length, both functions return the same number, the for loop is fine with one small change. The ".length()" and ".size()" functions return a "size_t" variable which is an "unsigned" something. The "something" part will depend on your compiler header files and how "size_t" is defined. This could be an "int" or a "long" or maybe something else. Either way defining "i" as a "size_t" means the the types will match. Not usually an error, but a warning that can be avoided.

I am not sure what you intended with line 7, but for now I put a comment on it.

The ".at(?)" has its use, but not here. the []s are sufficient since the for loop limits how far the loop will go. The ".at(?) function is just extra work that is not needed. In a very large file you might see the program slow down processing all the ".at(?)" functions.

I made one change in "main":
1
2
3
4
5
6
7
8
9
10
11
int main()
{
    Files dictonary;
    //intro();

    dictonary.read();

    dictonary.display();

    return 0;  // <--- Not required, but makes a good break point.
}

It is a smalll change and you can shorten it to "dict" if you want, but it is much better than just "d".

Andy
Hello nakash,

Forgot to mention the output from the program is:
 number of line 6 abacination

The vector elements are:

bleeping
damned.
adj

blemishless
Without blemish; spotless.
adj

blendous
Pertaining to consisting of or containing blende.
adj

abaca
The Manila-hemp plant (Musa textilis); also its fiber. See Manila hemp under Manila.
n

abacinate
To blind by a red-hot metal plate held before the eyes.
v

abacination
The act of abacinating.
n



A last minute thought:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int Files::read()
{
    //Files d;  // <--- Local variable that overshadows what is defined in "main".
    int i = 0;
    string word;
    string definition;
    string type;
    string blank;
    //vector<string>words;  // <--- Local variable that overshadows the class variable.

    ifstream inFile("Text1.txt");

    if (!inFile)
    {
        perror("\n\n     File error");

        return 1;
    }

And at the end of the function before the closing } put return 0;

Then in "main":
1
2
3
4
int returnValue{};

if (returnValue = dictonary.read())
    return returnValue;

One advantage is that you return to "main" before you leave the program, so everything can be cleaned up before the program ends. In this small program it may not seem very useful right now, but in the future when you have multiple functions opening multiple files. Returning 1 or 2 or 3 from the fifferent functions can help to track down where the problem is.

Andy
From the previous post http://www.cplusplus.com/forum/beginner/272579/ 'able to search them to find out their meanings and types'

For best performance search, the data should be stored sorted by word name. Nothing is said that the data held in the file is stored in the required sorted order - so assume it's not. Therefore there is a choice 1) Use a structure such as a vector and then sort it or 2) Use an associative container such as map which uses a black/red tree to store the data in sort order for efficient searching.

For 1), if the 3 parts of the data are held in separate vectors, then when the word vector is sorted the others need to be kept in sync - so a custom sort is required. If a struct of the 3 parts is used with a vector of this struct, then the standard sort() function can be used with a custom comparator. Then something like std::equal_range() could be used to find a required element.

However with 2), the sort is automatic and searching is easy. IMO this is the better way in this case. Consider using a map:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <utility>

using namespace std;

struct Entry
{
	string definition;
	string type;
};

using PT = pair<const string, Entry>;

ostream& operator<<(ostream& os, const PT& ent)
{
	return os << ent.first << ' ' << ent.second.definition << ' ' << ent.second.type << '\n';
}

class Dictionary
{
private:
	map<string, Entry> store;
	string file;

public:
	Dictionary(const string& aFile) : file(aFile) {}

	bool read();
	void display();
	void find(const string& wd);
};

void Dictionary::display()
{
	std::cout << "The vector elements are:\n";

	for (const auto& s : store)
		cout << s << '\n';
}

bool Dictionary::read()
{
	ifstream out(file);

	if (!out.is_open())
		return false;

	string dummy;
	string word;
	Entry temp;

	while (getline(out, word) && getline(out, temp.definition) && getline(out, temp.type) && getline(out, dummy))
		store.emplace(word, temp);

	out.close();

	return true;
}

void Dictionary::find(const string& wd)
{
	if (const auto f = store.find(wd); f != store.end())
		cout << *f << '\n';
	else
		cout << "Not found\n";
}

int main()
{
	Dictionary my_dictionary("dictionary.txt"s);

	if (!my_dictionary.read())
		return (cout << "Cannot open dictionary file\n"), 1;

	my_dictionary.display();

	for (string inp; (cout << "Enter word to find (<CR> to terminate): ") && getline(cin, inp) && !inp.empty(); )
		my_dictionary.find(inp);
}

Topic archived. No new replies allowed.