STL and FILE I/O problems

Hi! I'm experiencing some problems in C++...

1. STL
I'm using a map template like:-
map<string, string>table;
to implement a sort of a word->meaning table. And I intend to
- read a string
- recognize the words in the string by comparing the table keys with the strings
- print the meaning of the word.

And here lies the problem:-
The comparison and printing of the definitions is correct, but it's not "reading" from the left of the string to the right. It reads according to the "index" or the way it stores data elements inside it. Debugging the program showed it stores and reads lexically, meaning that if I store "the" first and "as" second, and the string is "the as", it will display as:-
as the

when the output should be
the as

How can i make it so that it "reads from the left to the right" and not from the way it stores data inside itself...?

I've browsed over different sites and I've tried numerous ways to solve this problem, but to no avail... I've tried using an unordered_map and then sorting it using a list, but the result is same as a normal map...
I've even tried using char* instead of strings like:-
map<char*, char*>table;
and still to no avail.
I've also tried using the relational operators, like:-
1
2
3
map<char*,char*,std::less<char*>table;
OR
map<string,string,std::greater<string>table;

but still no proper output...

Help me on this, please!

2. FILE I/O
My code is something like this (just for a general idea):-
1
2
3
4
5
6
7
8
9
10
11
12
13
ifstream file_in[filename];
string str_line;
while(file_in.good())
{
   getline(file_in,str_line);
   cout << str_line << endl;
}

while(file_in.good())
{
 getline(file_in,str_line);
   cout << str_line << endl;
}

The main idea is to read the same file twice.

The output is blank!
My compiler doesn't even the reach the body of the first loop, it just stops there and shows a blank output!

I've even tried using another ifstream object, like:-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ifstream file_in[filename];
ifstream temp_file_in[filename];
string str_line;
while(temp_file_in.good())
{
   getline(temp_file_in,str_line);
   cout << str_line << endl;
}

while(file_in.good())
{
 getline(file_in,str_line);
   cout << str_line << endl;
}

But the output is still the same: blank!

The code only works when I remove/comment out the first loop.
What's happening here and what's the solution?

Thanks (in advance).... :)
can you post code for problem - 1. A map will store the data, the way you feed it. Its not going to change the order of text. It will just keep your data sorted.

I think the line-1 is like this - ifstream temp_file_in(filename);

the code looks fine. Could you post more code related to this. May be some part of the file too.
Hi, thanks for the reply.

PROBLEM#01
A small portion of the code is:-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
map<char*, char*> table;
	
table["why"] = "word_why";
table["hello"] = "word_hello";
table[")"] = "RIGHT_PARENTHESIS";
table["("] = "LEFT_PARENTHESIS";

map<char*, char*>::iterator table_it;

string str = "why hello()";

for (table_it = table.begin() ; table_it != table.end(); table_it++) 
{
	int pos = str.find(table_it->first);
	if(pos != -1)
		cout << table_it->second << endl;
}


OUTPUT:-

word_hello
word_why
RIGHT_PARENTHESIS
LEFT_PARENTHESIS


I want it like

word_why
word_hello
LEFT_PARENTHESIS
RIGHT_PARENTHESIS





PROBLEM#02

I think the line-1 is like this - ifstream temp_file_in(filename);

Sorry about that, that was a typo.

The input file contains "why hello()".
As for the code, it's pretty much the same as above.
I'll re-write it:-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ifstream file_in(filename);
ifstream temp_file_in(filename);
string str_line;
while(temp_file_in.good())
{
   getline(temp_file_in,str_line);
   cout << str_line << endl;
}

while(file_in.good())
{
 getline(file_in,str_line);
   cout << str_line << endl;
}


EDIT: the file is a text file (i.e. "input.txt")
Last edited on
A map stores its elements in a way to assert fast access. Therefore std::map uses a tree sorting it by the comparison function given on instantiation. In your case this will be std::greater<string>. std::map ideally access elements in O(ld(n)).
std::unordered_map uses a hash table which finds an element nearly in O(1).


If you want fast access and your order, you may

1. find a totally order on your set of elements and define a sorting function accordingly, or

2. Define your own container, which is a std::map and additionally has a std::vector or sorted list which may serve to order your items. It may contain std::pair elements from your map to avoid redundant data and to assert uniqueness.
Fast access is not an issue here... I just want them "sorted" the way I want them to... To make it access it's elements as though it's "reading a sentence from left to right"... NOT randomly...
> How can i make it so that it "reads from the left to the right" and not from the way it stores data inside itself...?

In conjunction with the std::map<>, maintain a std::vector<> of std::map<>::iterators

Or use boost::multi_index<>

See: http://v2.cplusplus.com/forum/general/61253/



> The main idea is to read the same file twice.

Something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <fstream>

int main()
{
    // read a file twice, line by line
    std::ifstream file( __FILE__ ) ;
    std::string line ;

    while( std::getline( file, line ) ) // canonical
        std::cout << line << '\n' ;

    // the stream is now in a failed state and at eof.

    // to read it again:
    // 1. clear the failed state
    file.clear() ;
    // 2. seek to the beginning of the file
    file.seekg(0) ;
    // 3. and now repeat
    while( std::getline( file, line ) ) // canonical
        std::cout << line << '\n' ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
map<char*, char*> table;
	
table["why"] = "word_why";
table["hello"] = "word_hello";
table[")"] = "RIGHT_PARENTHESIS";
table["("] = "LEFT_PARENTHESIS";

map<char*, char*>::iterator table_it;

string str = "why hello()";

for (table_it = table.begin() ; table_it != table.end(); table_it++) 
{
	int pos = str.find(table_it->first);
	if(pos != -1)
		cout << table_it->second << endl;
}

The problem is not with the container type. The container is fine. The problem is that you're traversing the container, while you should be traversing (parsing) the string. Where's your parser?

As for the second problem - you need to reset the current position within the file back to the beginning of the file before performing the second loop. Or just close the file and re-open it.
Last edited on
Topic archived. No new replies allowed.