writing into a map from a file

i am trying to get the contents of a file in to a map. in a more detailed explanation:
the file im reading from is a .txt file and is open in regular format (only std::ios::in).
the map is of type: std::map<char,std::vector<bool> >
and the operation i want to do is as following: read from the file and write into a map and print on the screen.

file content example:
000110111110

11101010
110
.111011
A000110100
B000110111111
C1110101110
D1110101111
E00011011010
F0000001100
G00011011011
H000110010
I0001101100
J00011011100
L0000001101
M000110011
N000000000
O000000001
P000000010
R0000001110
S000000011
T00011011101
U000000100
W0000001111

(no spaces between the characters and their code)

and the output on the console should be:
:000110111110

:11101010
:110
.:111011
A:000110100
B:000110111111
C:1110101110
D:1110101111
E:00011011010
F:0000001100
G:00011011011
H:000110010
I:0001101100
J:00011011100
L:0000001101
M:000110011
N:000000000
O:000000001
P:000000010
R:0000001110
S:000000011
T:00011011101
U:000000100
W:0000001111

i only succeeded in reading each line into a string (with getline) but than im at a lose of knowledge of how to separatly put the characters into the char portion of the map and the code into the std::vector<bool> part
Note:i know how to work with maps, my problem is translating the string into the map in the correct way.

** if you have any other advise other than using a string as a man in the middle to transfer the data from the file into the map im open to other methods**
i know how to work with maps, my problem is translating the string into the map in the correct way.

Okay, then for the first four lines in the above, what is the "key"? Remember the "key" in a map must be unique.

Next, reading the file into a string with getline() is a good idea since it appears that the vectors will have a different number of elements.

Once you read the string use a stringstream to process each line. First get the key, then extract the rest of the information pushing "true" or "false" into your vector depending on the value of the character (0/1).

the first 4 lines are new line space eof and a strange symbol of a dot
and i still cant understand how to process it should i use [0] to adress the character or do it in another way? with stringstream if i try to extract numbers dont forget that there is a new line character (ascii 0x10) at the end of the line how can i extract the 0's and 1's without the newline? and last question is if i do extract with stringstream should i extract into a int and than into the vector or use stringstream on every 0 or 1 individually and straight store it in the vector?
the first 4 lines are new line space eof and a strange symbol of a dot

Those whitespace characters will complicate things a little if you use getline(). What do you mean by "strange symbol of a dot"? What is the numeric value of this character?

dont forget that there is a new line character (ascii 0x10) at the end of the line

By default getline() extracts and discards the new line character. The problem will be the leading whitespace characters. You will need to determine, in the case of the leading whitespace character you need to determine whether or not you have a colon and where in the string is this colon located. Remember that by default the getline() function stops processing the string when it encounters a new line character, and by default skips all other leading whitespace.

how can i extract the 0's and 1's without the newline?

Remember that those zeros and ones are characters, not numbers when processing your string. You read the character test if it is a '0' or '1' and push the proper bool value into your vector.

and last question is if i do extract with stringstream should i extract into a int and than into the vector or use stringstream on every 0 or 1 individually and straight store it in the vector?

Remember your vector is a vector<bool> you need to push the proper boolean value into the vector, ie: true or false. You can't easily retrieve a number from the string, how would you know that the number is 0 1 0 1 not 0101? Retrieve the values from the stream as characters, test the character and push the proper boolen value into your vector.



iv'e done the following:

.h
1
2
3
4
5
6
7
8
9
10
namespace file_info {
	class scanner {
	private:
		std::ifstream _scanner_file;
		std::stringstream _buffer;
	public:
		void set_file_copy(std::string& file_loc);
		std::string get_file_copy() const;
	};
}


.cpp
1
2
3
4
5
6
7
8
9
10
11
12
void file_info::scanner::set_file_copy(std::string& file_loc) {
	_scanner_file.open(file_loc, std::ios::in);
	if (_scanner_file.is_open()) {
		_buffer << _scanner_file.rdbuf();
		_scanner_file.close();
	}
	else std::cout << "Unable to open the file for copy operation." << std::endl;
}

std::string file_info::scanner::get_file_copy() const {
	return _buffer.str();
}


.h
1
2
3
4
5
6
7
8
9
10
11
namespace decoder {
	class decompressor {
	private:
		file_info::scanner _decode_key;
		std::vector<bool> _character_code;
		std::map<char, std::vector<bool> > _character_table;
	public:
		void _get_key(std::string& decoding_key_loc);
		void print();
	};
}


.cpp
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
void decoder::decompressor::_get_key(std::string& decoding_key_loc) {
	std::string buffer;
	_decode_key.set_file_copy(decoding_key_loc);
	buffer = _decode_key.get_file_copy();
	for (int str_itr = 0; str_itr < (buffer.length() - 1); str_itr++) {
		if ((buffer[str_itr] != '1') && (buffer[str_itr] != '0')) {
			char character = buffer[str_itr];
			++str_itr;
			do {
				if (buffer[str_itr] == '0') {
					_character_code.push_back(0);
				}
				else if (buffer[str_itr] == '1') {
					_character_code.push_back(1);
				}
				++str_itr;
			} while ((buffer[str_itr] == '1') || (buffer[str_itr] == '0'));
			_character_table[character] = _character_code;
			_character_code.clear();
		}
	}//for
}

void decoder::decompressor::print() {
	for (std::map<char, std::vector<bool> >::iterator map_itr = _character_table.begin(); map_itr != _character_table.end(); map_itr++) {
		std::cout << map_itr->first << ":";
		for (std::vector<bool>::iterator vec_itr = _character_table[map_itr->first].begin(); vec_itr != _character_table[map_itr->first].end(); vec_itr++) {
			std::cout << *vec_itr;
		}
		std::cout << std::endl;
	}
}
[code]

Note:they share the same .h and .cpp files just encapsulated in namespaces.

.main
[code]
int main(){
std::string key = "C:/Users/User/Desktop/key.txt";
decoder::decompressor test;
test._get_key(key);
test.print();
return 0;
}


**UPDATE:i changed the file format to:
000110111110
11101010 110.111011A000110100B000110111111C1110101110D1110101111E00011011010F0000001100G00011011011H000110010I0001101100J00011011100L0000001101M000110011N000000000O000000001P000000010R0000001110S000000011T00011011101U000000100W0000001111a0011b1110100c00001d11110e011f101111g101110h00010i1010j000110101k00011000l10110m111110n1001o1000p111000q000000101r0100s0101t0010u111111v000001w000111x111010110y111001z00011011110

the key.txt contains the above.

the problem is that it ignores the long white space and skips over a character every time the problem will be easier to understand if compiled and run.

Note: the libraries used are:
1
2
3
4
5
#include<iostream>
#include<fstream>
#include<sstream>
#include<vector>
#include<map> 
the problem is that it ignores the long white space

What do you mean that it ignores the long whitespace? Do you realize that the extraction operator>>, by default, stops processing a string when it encounters a whitespace character?


What is your output with your current input file?

**UPDATE:i changed the file format to:

Why, IMO your first file format is the better choice since it is much easier for a human to read.

the white space means an empty line in the file and has its code on the second line of the new format "11101010" and i changed the format because it shouldn't be human readable its meant to be machine readable as it is a key and than stored in a map
Well it shouldn't ignore that empty line, the processing of your string should stop. Remember that when retrieving data into a string the extraction operator stops processing the stream when it encounters a whitespace character. And since you only try the extraction once it should stop processing the stream at that point.

Also remember that by default getline() stops processing a the stream when it encounters a new line character. Because you have embedded whitespace characters, including the new line character, you probably will want to read the file character by character. And don't forget you can't use a signed char because that "strange symbol of a dot" seems to be several bytes long and the values of those bytes are larger than what a signed character can hold.


yes but what is the problem in my code i don't use anything you list above.
i use rdbuf() it reads the whole content into a string
update:
the strange symbol ascii is -1 which i figured out to be "eof" character
the blank space ascii is 10 which is new line
and the single white space ascii is 32 which is space
after this "discovery" i have changed the question how can i properly read into a map the symbols listed above *from the file*?
the strange symbol ascii is -1 which i figured out to be "eof" character

There is no such thing as an "eof" character. That strange character has a value larger than what can be held in a signed char and it also seems to be some kind of a multi-byte character. Which means trying to use a std::string to hold it's content will probably not work.

Where exactly did this file come from?

How was the file generated?

What operating system was used to generate the file?

What is the "locale" of the system used to generate the file?

-i used rdbuf to store the file content into a string and it works and from testing it holds all of the information including the -1 Ascii.
-the file was generated by a huffman encoder i made, i can change its format in any way to fit the needs.
- the op i use is windows 8.1 but also have linux in vm and the encoder works there aswell.
-the locale is english us and the file is of type .txt while the key generated inside using open(std::ios::out)
thanks for trying to provide help with the problem i finally came to a solution and it works exactly as i wanted!
Topic archived. No new replies allowed.