Stringstream Consectutive Whitespace

So I have a text file named test.txt on the root of my c:/drive.

I finally managed to arrays working and reading into them, but when I started looking at the data in the array I noticed that stringstream was not "grabbing" a specified space. LINES 83-88

The text file contains the following (note that there is an intentional space after the first word):
I ' m s o r 0 y 4 D a v e , 5 12 12 12 3 7 f 11 2 i d 5 8 1 c 5 n 10 t 5 7 17 2 3 h 7 2 .

I need that space to be caught in the steam, there will always be only one space after a various first word, but I need it in my array and stringstream doesn't catch it.

if you need to run it, just copy the text to a file named c:/test.txt

When you run the code, you will see after the 3rd iteration it skips the space, is there a way to change this, so I can focus on the decryption algorithm?? ANY help would be greatly appreciated.

Thanks,
BP

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdio.h>
#include <sstream>
#include <cctype>

bool is_number(const std::string& s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
}

int main()
{
	std::string file_path;
	std::string line;
	int listCount=0;
	int row=0;
	int col=0;
	int maxcol=0;
	
	//Get file path & name & store in file_path
	//cout << "What is the location of the file to decrpyt?"<< std::endl;
	//cin >> file_path;
	file_path = "c:/test.txt";
	//Open Stream from file
	std::ifstream fin;
	fin.open(file_path);
	if (fin.is_open())
	{
		while ( getline (fin ,line) )
		{
			std::string linestring = line;
			col = 0;
            std::cout << linestring << "line #"<< row << std::endl << std::endl;
			std::stringstream os(linestring);			
			std::string temp;					
			while (os >> temp)
			{
				//std::cout <<temp <<std::endl;		
				if(!is_number(temp))
				{
					listCount+=1;
				}
				col+=1;
				if (maxcol<col)
				{
					maxcol=col;
				}
			}										
			row+=1;			
		}
	}
	else 
	{
		std::cout << "Unable to open file"; 
	}

	//Now that i have looped through the file once to get the sizes, i clear the flags and reopen the file
	fin.clear();
	fin.close();
	fin.open(file_path);
	if (fin.is_open())
	{
		//create the array based on sizes obtained above
		std::string **encryptedarray = new std::string*[maxcol];
		for(int i = 0; i < maxcol; ++i) 
		{
			encryptedarray[i] = new std::string[row];
		}
		std::string **decryptedarray = new std::string*[maxcol];
		for(int i = 0; i < maxcol; ++i) 
		{
			decryptedarray[i] = new std::string[row];
		}
		std::string listArray[300];
		row = 0;
		while ( getline (fin ,line) )
		{
			std::string linestring = line;
			std::stringstream os(linestring);			
			std::string temp;
			col=0;
			//os >> std::noskipws;
			while (os >> temp)
			{
				std::cout << "Next character read from the stream is " << temp <<std::endl;
				//NONE OF TRHIS WORKS UNTIL I GET THE SPACE TO BE READ FROM THE FILE AS A TOKEN/value
				encryptedarray[col][row] = temp;
				if(is_number(temp))
				{
					//IF temp is a number assign it to value
					int value = std::stoi(temp);
					decryptedarray[col][row]= listArray[value];
					std::string swap = listArray[value];
					for(int i=value;i>0;--i)
					{
						listArray[i]=listArray[i-1];
						//std::cout << "list array values " << listArray[i] <<std::endl;
					}
					listArray[0]=swap;
					//std::cout << "number found in temp " << temp <<std::endl;
					//std::cout << "number found in value " << value <<std::endl;
				}
				else
				{
					decryptedarray[col][row] = temp;
					std::cout << "The current list is now ";
					for(int i=listCount;i>0;--i)
					{
						listArray[i]=listArray[i-1];
						std::cout << listArray[i];
					}
					listArray[0]=temp;
					std::cout << std::endl<<std::endl;
					system("PAUSE");
					std::cout << std::endl<<std::endl;
				}
				col+=1;
			}
			row+=1;
		}
		for(int r=0;r<row;++r)
		{
			for(int i=0;i<maxcol;++i)
			{
				std::cout << encryptedarray[i][r];
			}
		}
		std::cout <<std::endl;
		for(int r=0;r<row;++r)
		{
			for(int i=0;i<maxcol;++i)
			{
				std::cout << decryptedarray[i][r];
				
			}
			
		}
		
	}
	else 
	{
		std::cout << "Unable to open file"; 
	}
	system("PAUSE");
}
Last edited on
It is not quite clear how you want a line to be tokenized into strings.

Perhaps, an example would help. For instance,

For this line I ' m s o r 0 y 4 D a v e , 5 12 12 12 3 7 f 11 2 i d 5 8 1 c 5 n 10 t 5 7 17 2 3 h 7 2 .

The tokens should be:
1. I ' m s o r 0 y 4 D a v e,
2. 5
3. 12
...

 
I ' m   s o r 0 y 4 D a v e , 5 12 12 12 3 7 f 11 2 i d 5 8 1 c 5 n 10 t 5 7 17 2 3 h 7 2 . 

Sorry about that, it appears when I pasted the contents of the text file it removed multiple spaces. There is one space between every token in the list. There are 3 spaces after "I ' m"

so currently it tokens out as:
1. I
2. '
3. m
4. s
5. o

This is almost perfect, except it is misses grabbing the space as a token for # 4. After that they are all correct, but in the wrong place in my arrays because of it skipping the space at #4. For the number four I would like to have " " placed into temp so I can put in into my array, but currently it gets skipped.
Can't you just remove every-other character from the string? This isn't a job for tokenization.
Something like this, perhaps:

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
#include <iostream>
#include <string>
#include <vector>
#include <sstream>

int main()
{
    const std::string space( 1, ' ' ) ;
    const std::string three_spaces = space + space + space ;
    std::string str = "I ' m   s o r 0 y 4 D a v e , 5 12 12 12 3 ." ;

    // locate three consecutive spaces in the string
    auto pos = str.find(three_spaces) ;
    if( pos != std::string::npos ) // if found
    {
        // the part before three consecutive spaces
        std::string part_one = str.substr( 0, pos ) ;

        // the part after three consecutive spaces
        std::string part_two = str.substr( pos + three_spaces.size() ) ;

        // string with the middle space of the three consecutive spaces
        // replaced with a nullchar
        constexpr char nullchar = 0 ;
        str = part_one + space + nullchar + space + part_two ;

        // parse this string as in the earlier code
        std::vector<std::string> array ;
        std::istringstream stm(str) ;
        std::string temp ;
        while( stm >> temp )
        {
            // except that if it is a nullchar, replace it with a space
            if( temp.front() == nullchar ) array.push_back(space) ;
            else array.push_back(temp) ;
        }

        // dump the contents of the array to check it out
        int n = 0 ;
        for( const std::string& token : array )
            std::cout << ++n << ". \"" << token << "\"\n" ;
    }
}

http://coliru.stacked-crooked.com/a/9f7d3dff302a6387
Thanks for the help Your code works great for a single line, but when I attempted to use it to read multiple lines using getline it does not get a second line. Am I missing something, as I have never used a 2d vector. I really appreciate the help, the sad part is I figured the algorithm for decryption out easily... i just cant seem to get the correct data into an 2d array/vector

ALl I need to do is read EACH line of the text file into an array/vector row and then every token into a column. so that if the text file was:

I did change from using the hard coded string to using line, I really appreciate what you showed me thus far... looks like it would take a lot less code to accomplish this now, since I will not have to loop through the file one time to get the size to create arrays. Thanks Again

1
2
3
4
I ' m   s o r 0 y 4 D a v e , 
5 12 12 12 3 7 f 11 2 i d 5 8 1 c 5 n 

10 t 5 7 17 2 3 h 7 2 .  


my array/vector would need to be
ROW 1 ----> I ' m s o r 0 y 4 D a v e ,
ROW 2----->5 12 12 12 3 7 f 11 2 i d 5 8 1 c 5 n
ROW 3----->EMPTY
ROW 4----->10 t 5 7 17 2 3 h 7 2 .

once I get it into a 2d vector, I need to know the height & MAX width so I can use a loop to access it via encryptedarray[col][row] and then perform processing on each string of the array to decrypt it to decryptedarray like I was doing earlier when I couldn't capture the null space.

Commented my code out and was editing line by line until i realized I was not getting the second line
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdio.h>
#include <sstream>
#include <cctype>


bool is_number(const std::string& s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
}

int main()
{
	std::string file_path;
	std::string line;
	int listCount=0;
	int row=0;
	int col=0;
	int maxcol=0;
	const std::string space( 1, ' ' ) ;
    const std::string three_spaces = space + space + space ;
	const char nullchar = 0 ;
	std::vector<std::string> encryptedarray1;
	std::vector<std::string> decryptedarray1;

	//Get file path & name & store in file_path
	//cout << "What is the location of the file to decrpyt?"<< std::endl;
	//cin >> file_path;
	file_path = "c:/test.txt";
	//Open Stream from file
	std::ifstream fin;
	fin.open(file_path);
	if (fin.is_open())
	{
		while ( getline (fin ,line) )
		{
			std::string linestring = line;
			auto pos = line.find(three_spaces) ;
			if( pos != std::string::npos ) // if found
			{
				// the part before three consecutive spaces
				std::string part_one = line.substr( 0, pos ) ;

				// the part after three consecutive spaces
				std::string part_two = line.substr( pos + three_spaces.size() ) ;
        
				line = part_one + space + nullchar + space + part_two ;

				// parse this string as in the earlier code
				//std::vector<std::string> array ;
				col = 0;
				std::istringstream stm(line) ;
				std::string temp ;
				while( stm >> temp )
				{
					// except that if it is a nullchar, replace it with a space
					if( temp.front() == nullchar ) encryptedarray1.push_back(space) ;
					else encryptedarray1.push_back(temp) ;
					
					if(!is_number(temp))
					{
						listCount+=1;
					}
					col+=1;
					if (maxcol<col)
					{
						maxcol=col;
					}
				}

				// dump the contents of the array to check it out
				int n = 0 ;
				for( const std::string& token : encryptedarray1 )
				std::cout << ++n << ". \"" << token << "\"\n" ;

				
				std::string linestring = line;
				col = 0;
				std::cout << linestring << "line #"<< row << std::endl << std::endl;
				

                                                             /* 
				std::stringstream os(linestring);						
				while (os >> temp)
				{
					
					//std::cout <<temp <<std::endl;		
					if(!is_number(temp))
					{
						listCount+=1;
					}
					col+=1;
					if (maxcol<col)
					{
						maxcol=col;
					}
					
				}
				
				row+=1;	
				*/
			}
		}
	}
	else 
	{
		std::cout << "Unable to open file"; 
	}  


	/* COMMENTED OUT FROM HERE TO END  FOR TESTING
	//Now that i have looped through the file once to get the sizes, i clear the flags and reopen the file
	fin.clear();
	fin.close();
	fin.open(file_path);
	if (fin.is_open())
	{
		//create the array based on sizes obtained above
		std::string **encryptedarray = new std::string*[maxcol];
		for(int i = 0; i < maxcol; ++i) 
		{
			encryptedarray[i] = new std::string[row];
		}
		std::string **decryptedarray = new std::string*[maxcol];
		for(int i = 0; i < maxcol; ++i) 
		{
			decryptedarray[i] = new std::string[row];
		}
		std::string listArray[300];
		row = 0;
		while ( getline (fin ,line) )
		{
			std::string linestring = line;
			std::stringstream os(linestring);			
			std::string temp;
			col=0;
			//os >> std::noskipws;
			while (os >> temp)
			{
				std::cout << "Next character read from the stream is " << temp <<std::endl;
				//NONE OF TRHIS WORKS UNTIL I GET THE SPACE TO BE READ FROM THE FILE AS A TOKEN/value
				encryptedarray[col][row] = temp;
				if(is_number(temp))
				{
					//IF temp is a number assign it to value
					int value = std::stoi(temp);
					decryptedarray[col][row]= listArray[value];
					std::string swap = listArray[value];
					for(int i=value;i>0;--i)
					{
						listArray[i]=listArray[i-1];
						//std::cout << "list array values " << listArray[i] <<std::endl;
					}
					listArray[0]=swap;
					//std::cout << "number found in temp " << temp <<std::endl;
					//std::cout << "number found in value " << value <<std::endl;
				}
				else
				{
					decryptedarray[col][row] = temp;
					std::cout << "The current list is now ";
					for(int i=listCount;i>0;--i)
					{
						listArray[i]=listArray[i-1];
						std::cout << listArray[i];
					}
					listArray[0]=temp;
					std::cout << std::endl<<std::endl;
					system("PAUSE");
					std::cout << std::endl<<std::endl;
				}
				col+=1;
			}
			row+=1;
		}
		for(int r=0;r<row;++r)
		{
			for(int i=0;i<maxcol;++i)
			{
				std::cout << encryptedarray[i][r];
			}
		}
		std::cout <<std::endl;
		for(int r=0;r<row;++r)
		{
			for(int i=0;i<maxcol;++i)
			{
				std::cout << decryptedarray[i][r];
				
			}
			
		}
		
	}
	else 
	{
		std::cout << "Unable to open file"; 
	}
	system("PAUSE");
	*/
                system("PAUSE");
}

Last edited on
LB if i removed every other char it would not work, as i understand it.

I have to be able to read the spaces seprated values into a 2d array/vector and keep the same "number of lines" in the text file

Then use various decryption algorithms on each value in the 2d array/vector and output it to a indentically sized decrypted vector before outputting it to the screen and file.

If you have an easier solution to get it loaded into an array/vector i am all ears.

Thanks
BP
Brntphish wrote:
LB if i removed every other char it would not work, as i understand it.
Removing 'every other char' is just getting rid of the spaces in between each character in the string. Then if for some reason you want to, you can read each character of the resulting string into a vector...
but that would lose the space after "I'm" and I need it as well, and if I got rid of the spaces I would not be able to know whether 151 was 1 51, 1 5 1, 15 1. I am gonna be casting the numeric values to ints later in the prog, so unless I misunderstand, I don't think striping the space will work
Brntphish wrote:
but that would lose the space after "I'm"
No, it would not.
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
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>

int main()
{
    constexpr char nullchar = 0 ;
    const std::string space( 1, ' ' ) ;
    const std::string three_spaces = space + space + space ;
    const std::string file_path = "c:/test.txt";

    std::ifstream fin(file_path) ;

    // the nested vector of tokens in each line
    // tokens_in_all_lines would contain one std::vector<std::string> for each line
    //     which would contain the extracted tokens for that particular line
    std::vector< std::vector<std::string> > tokens_in_all_lines ;

    std::string line ;
    while( std::getline( fin, line) ) // for each line in the file
    {
        // split it up into tokens
        std::vector<std::string> tokens_in_this_line ;

        // see if there are three consecutive spaces in this particular line
        auto pos = line.find(three_spaces) ;
        if( pos != std::string::npos ) // if found
        {
            // the part before three consecutive spaces
            std::string part_one = line.substr( 0, pos ) ;

            // the part after three consecutive spaces
            std::string part_two = line.substr( pos + three_spaces.size() ) ;

            // replace the middle space of the three consecutive spaces
            // replaced with a nullchar
            line = part_one + space + nullchar + space + part_two ;
        }

        // parse this line as in the earlier code
        std::istringstream stm(line) ;
        std::string temp ;
        while( stm >> temp )
        {
            // except that if it is a nullchar, replace it with a space
            if( temp.front() == nullchar ) tokens_in_this_line.push_back(space) ;
            else tokens_in_this_line.push_back(temp) ;
        }

        // add the extracted tokens to tokens_in_all_lines
        tokens_in_all_lines.push_back(tokens_in_this_line) ;
    }

    // determine the max number of columns
    std::size_t max_width = 0 ;
    for( const auto& tokens : tokens_in_all_lines )
        if( max_width < tokens.size() ) max_width = tokens.size() ;

    std::cout << "#lines: " << tokens_in_all_lines.size() << '\n'
               << "max width: " << max_width << '\n' ;
}
Last edited on
GREAT Solution, half the size of my initial code, since I only have to iterate through it once now using vectors.

I have searched and search for the last piece of my puzzle... I keep getting subscript out of range errors when accessing the vector. I am no doubt doing it wrong.... and have came up empty due to the fact that everything I read says to access it the same way as a 2d array (vector[x][y]).
So I commented out all of my code/pseudo code and just tried a cout, and I still got the error, so I am definitely sure I am accessing it incorrectly. ( I commented in the code as well Line 72-76)

could someone shed some light on why line 69 is giving subscript out of range?
PROBLEM CODE:
1
2
3
4
5
6
7
8
for(int r=0;r<row;++r)
		{
			for(int i=0;i<max_width;++i)
			{
				std::cout << tokens_in_all_lines[r][i]<< std::endl;
				system("PAUSE");
			}
		}



COMPLETE CODE:
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>

int main()
{
    const char nullchar = 0 ;
    const std::string space( 1, ' ' ) ;
    const std::string three_spaces = space + space + space ;
    const std::string file_path = "c:/test.txt";

    std::ifstream fin(file_path) ;

    // the nested vector of tokens in each line
    // tokens_in_all_lines would contain one std::vector<std::string> for each line
    //     which would contain the extracted tokens for that particular line
    std::vector< std::vector<std::string> > tokens_in_all_lines ;

    std::string line ;
    while( std::getline( fin, line) ) // for each line in the file
    {
        // split it up into tokens
        std::vector<std::string> tokens_in_this_line ;

        // see if there are three consecutive spaces in this particular line
        auto pos = line.find(three_spaces) ;
        if( pos != std::string::npos ) // if found
        {
            // the part before three consecutive spaces
            std::string part_one = line.substr( 0, pos ) ;

            // the part after three consecutive spaces
            std::string part_two = line.substr( pos + three_spaces.size() ) ;

            // replace the middle space of the three consecutive spaces
            // replaced with a nullchar
            line = part_one + space + nullchar + space + part_two ;
        }

        // parse this line as in the earlier code
        std::istringstream stm(line) ;
        std::string temp ;
        while( stm >> temp )
        {
            // except that if it is a nullchar, replace it with a space
            if( temp.front() == nullchar ) tokens_in_this_line.push_back(space) ;
            else tokens_in_this_line.push_back(temp) ;
        }

        // add the extracted tokens to tokens_in_all_lines
        tokens_in_all_lines.push_back(tokens_in_this_line) ;
    }

    // determine the max number of columns
    std::size_t max_width = 0 ;
    for( const auto& tokens : tokens_in_all_lines )
        if( max_width < tokens.size() ) max_width = tokens.size() ;

    std::cout << "#lines: " << tokens_in_all_lines.size() << '\n'
               << "max width: " << max_width << '\n' ;
	int row = tokens_in_all_lines.size();

	for(int r=0;r<row;++r)
		{
			for(int i=0;i<max_width;++i)
			{
				std::cout << tokens_in_all_lines[r][i]<< std::endl;
				system("PAUSE");
				
				//I can figure the rest out if i you could help me understand why i getting subscript out of range errors
				//I Assume i am just not accessing it correctly, but have tried reversing the r & i positions as well
				//If goes through the first iteration but when attempting to go to col 2 i get the error
				//when i swapped then it gave an error when attemptting to go ro row 2
				//so i assume i am just nbot accessing it correctly



				//Check if value is number
				
				//if number do this
					//if token/string is number shift the list array based on number
					//cast token as a int to use as listarray[] subscript
					//add the value from list array to an decrypted array that was at the location indicated by the token
					//add the token to an decrypted array

				//else do this
					//add token/string to head of list array and shift existing array elements down
					//add the token to an decrypted array

				//END IF

				//Loop through decrypted array(same size as token_in_all_Lines vector
				//cout decrypted array and save to file output as well




				//THIS IS THE OLD CODE I HAVENT UPDATED IT YET because i cant get the above cout to work

				/* 
				if(is_number(tokens_in_all_lines[r][i]))
				{
					//IF temp is a number assign it to value
					int value = std::stoi(tokens_in_all_lines[r][i]);
					decryptedarray[col][row]= listArray[value];
					std::string swap = listArray[value];
					for(int i=value;i>0;--i)
					{
						listArray[i]=listArray[i-1];
						//std::cout << "list array values " << listArray[i] <<std::endl;
					}
					listArray[0]=swap;
					//std::cout << "number found in temp " << temp <<std::endl;
					//std::cout << "number found in value " << value <<std::endl;
				}
				else
				{
					decryptedarray[col][row] = temp;
					std::cout << "The current list is now ";
					for(int i=listCount;i>0;--i)
					{
						listArray[i]=listArray[i-1];
						std::cout << listArray[i];
					}
					listArray[0]=temp;
					std::cout << std::endl<<std::endl;
					system("PAUSE");
					std::cout << std::endl<<std::endl;
				}
				*/

			}
		}

	system("PAUSE");

	
}
OK i have determined that since line 1 of the file is shorter than line 2, when i access the vector using subscripts I get the error when I reach the "end" of the first row id the 2d, I say end because row 0 is shorter than row 1.

Knowing this, how would i resize the vector so that max_width is the same for all rows? (while not destroying existing data)

if i did a resize and added a default char, would it overwrite what is in the current vector location? or does it only apply to appended subscripts?

And then finally how do i resize so that width = max_width (may be max-width -1) have to look at code, and that height is (vector size -1)

It appears the height remains correct, but the width is required.. i figured i would do both so i wouldn't have to worry about blank lines, or anything else

So possibly could someone explain the syntax used to resize and set to a default string of XX

then when i mirror this into an array i can just just use if [col][row]=XX then insert nothing
Last edited on
I figured it out....
i resized without using a default value, which meant the added vectors contain nothing/""... so when i iterated i check for !="" first.

Thanks for the help.

Step 1 of decryption is complete. Entire Code below:
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cctype>

bool is_number(const std::string& s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
}

int main()
{
    const char nullchar = 0 ;
    const std::string space( 1, ' ' ) ;
    const std::string three_spaces = space + space + space ;
    std::string file_path;
	int listCount = 0;
		std::cout << "Name: Jeff Brown" << std::endl;
	std::cout << "Date: 10-01-2013" << std::endl;
	std::cout << "Email: " << std::endl;
	std::cout << "Email: " << std::endl<< std::endl;

	std::cout << "Please enter the full path to the file to be decrypted."<< std::endl;
	std::cout << "Path = ";
	std::cin >> file_path;
	std::cout << std::endl<<std::endl<<std::endl;
    std::ifstream fin(file_path) ;

    // nested vector
    // tokens_in_all_lines contains one std::vector<std::string> for each line
    // which contains the extracted tokens for that particular line
    std::vector< std::vector<std::string> > tokens_in_all_lines ;

    std::string line ;
    while( std::getline( fin, line) ) // while not EOF
    {
        // split into tokens
        std::vector<std::string> tokens_in_this_line ;

        // check for three consecutive spaces in this line indicating a space string
		// stringstream does not pick up consecutive spaces
        auto pos = line.find(three_spaces) ;
        if( pos != std::string::npos ) // if 3 spaces found
        {
            // before pos of three consecutive spaces
            std::string part_one = line.substr( 0, pos ) ;
			// after pos of three consecutive spaces
            std::string part_two = line.substr( pos + three_spaces.size() ) ;
			// replace the middle space of the three consecutive spaces
            // replaced with a nullchar
			//concatenate back to form a line
            line = part_one + space + nullchar + space + part_two ;
        }

        // parse this line
        std::istringstream stm(line) ;
        std::string temp ;
        while( stm >> temp )
        {
            // if nullchar, replace it with a space
            if( temp.front() == nullchar ) tokens_in_this_line.push_back(space) ;
            else tokens_in_this_line.push_back(temp) ;
        }

        // add extracted tokens to tokens_in_all_lines
        tokens_in_all_lines.push_back(tokens_in_this_line) ;


    }//get next line

    // determine the max number of columns
    std::size_t max_width = 0 ;
    for( const auto& tokens : tokens_in_all_lines )
        if( max_width < tokens.size() ) max_width = tokens.size() ;

	int row = tokens_in_all_lines.size();
	//Display Encrypted File
	std::cout << "---------------Begin Encrypted Message-------------"<<std::endl;
	for(int r=0;r<row;++r)
		{
			for(int i=0;i<max_width;++i)
			{
				tokens_in_all_lines[r].resize(max_width);
				std::cout << tokens_in_all_lines[r][i];
			}
				std::cout << std::endl;
		}
	std::cout << "---------------End Encrypted Message---------------"<<std::endl;
	std::cout << std::endl<< std::endl<< std::endl;

	// Begin to Decrypt Message one string/token at a time
	std::cout << "---------------Begin Decrypted Message-------------"<<std::endl;
	// An array to hold the non numeric strings from the file - arbitrary size
	std::string listArray[256];

	for(int r=0;r<row;++r)
		{
			for(int i=0;i<max_width;++i)
			{
				tokens_in_all_lines[r].resize(max_width);

				//Make sure vector isnt empty, if it is.. skip that iteration. Empty vector errors out if attempted to be accessed
				if(tokens_in_all_lines[r][i]!="")
				{
					//Check If value is not a number
					if(!is_number(tokens_in_all_lines[r][i]))
					{
						if(listCount==0)
						{
							listArray[listCount]=tokens_in_all_lines[r][i];
						}
						else
						{
							for(int l=listCount+1;l>0;--l)
							{
								listArray[l]=listArray[l-1];
							}
							listArray[0]= tokens_in_all_lines[r][i];
						}
						listCount+=1;
						std::cout << listArray[0];
					}
					//If it was not a number then it must be a number
					else
					{
						int value = std::stoi(tokens_in_all_lines[r][i]);
						std::cout << listArray[value];
						std::string swap = listArray[value];
						for(int n=value;n>0;--n)
						{
							listArray[n]=listArray[n-1];
						}
						listArray[0]=swap;
					}
				}
			}
				std::cout << std::endl;
		}
	std::cout << "---------------End Decrypted Message---------------"<<std::endl;
	std::cout << std::endl<< std::endl<< std::endl<< std::endl;

	system("PAUSE");	
}
Topic archived. No new replies allowed.