I'm having trouble iterating through a const string.

I'm trying to use a for loop to iterate through a const string to print the characters but I'm getting an error. If I remove the const for that string in the function parameters, the error is dismissed. I dont want to remove the const because I don't want to edit that string. The thing is that I'm not trying to edit the string. I'm just trying to set the iterator to the beginning of that string.

What am I doing wrong here?

Thanks.

 
no match for 'operator=' (operand types are 'std::__cxx11::basic_string<char>::iterator' {aka '__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >'} and 'std::__cxx11::basic_string<char>::const_iterator' {aka '__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >'})


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
void Legend_Screen(bool &Creator_Access,
			      bool &Admin_Access,
			      bool &Leader_Access,
			      bool &User_Access,
			      size_t &OTP_Character_Count,
			      std::string &Go_To_Screen,
		              const std::string Character_Legend){

	//Iterator declaration.
	std::string::iterator Character_Legend_Pointer;

	//Print the legend characters.
	for(Character_Legend_Pointer = Character_Legend.begin();
		Character_Legend_Pointer != Character_Legend.end();
		Character_Legend_Pointer++){

		//Print all characters except for the space.
		if(*Character_Legend_Pointer != ' '){

			//Print the legend characters.
			std::cout << *Character_Legend_Pointer << "  ";

		//Print the space using this.
		}else{

			//Print the word SPACE.
			std::cout << "SPACE";

		}

	}
}
Last edited on
1
2
//Iterator declaration.
std::string::const_iterator Character_Legend_Pointer; // line 10 


Consider using a range-based loop:
1
2
3
4
5
for( char c : Character_Legend )
{
    if( c == ' ' ) std::cout << "SPACE";
    else std::cout << c << ' ' ; // we assume that it is a printable character other than space
}


Ideally, pass the string by reference to const: const std::string& Character_Legend
Last edited on
Ahhh you beat me to it. I just figured it out and couldn't reply quick enough. Thanks! I'll try the range based loop.
Last edited on
Using iterator:

1
2
3
4
5
6
7
8
9
10
	for (auto Character_Legend_Pointer = Character_Legend.cbegin();
		Character_Legend_Pointer != Character_Legend.cend();
		++Character_Legend_Pointer) {

		//Print all characters except for the space.
		if (*Character_Legend_Pointer != ' ')
			std::cout << *Character_Legend_Pointer << "  ";
		else
			std::cout << "SPACE";
	}

CoreGuidelines:
Prefer a range-for-statement to a for-statement when there is a choice

Reason: Readability. Error prevention. Efficiency.
...
Enforcement Look at loops, if a traditional loop just looks at each element of a sequence, and there are no side effects on what it does with the elements, rewrite the loop to a ranged-for loop.

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-for-range
So the range for loop is awesome but for what im doing the regular for statement is easier. I think.

This is the whole function for my home screen.
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
//Home				################################################
void Legend_Screen(bool &Creator_Access,
				   bool &Admin_Access,
				   bool &Leader_Access,
				   bool &User_Access,
				   size_t &OTP_Character_Count,
				   std::string &Go_To_Screen,
				   const std::string Character_Legend){

	//String declaration.
	std::string User_Input,
				Character_Legend_Output_String,
				Legend_Character_Value_Output_String;

	//Iterator declaration.
	std::string::const_iterator Character_Legend_Pointer;

	//size_t declaration.
	int Legend_Character_Value = 0;

	//Scroll old screen up out of sight.
	std::cout << std::string(50, '\n' );

	//Print header art.
	Print_Header_ASCII_Art();

	//Print a line under the header art.
	std::cout << std::string(120, '_') << std::endl;

	//Print access type and current screen.
	if(Creator_Access){

		std::cout << "Access: Creator | Screen: Character Legend" << std::endl;

	}else if(Admin_Access){

		std::cout << "Access: Admin | Screen: Character Legend" << std::endl;

	}else if(Leader_Access){

		std::cout << "Access: Leader | Screen: Character Legend" << std::endl;

	}else if(User_Access){

		std::cout << "Access: User | Screen: Character Legend" << std::endl;

	}

	//Screen Body: 24 lines

	//Advance the console by one line.
	std::cout << std::string(2, '\n');

	//Print the character legend.
	for(Character_Legend_Pointer = Character_Legend.begin();
		Character_Legend_Pointer != Character_Legend.end();
		Character_Legend_Pointer++){

		//Check if the character is a space.
		if(*Character_Legend_Pointer == ' '){

			//If the character is a space, append the word SPACE instead.
			Character_Legend_Output_String.append("SPACE");

		}else{

			//Push back the character and insert spaces between each character.
			Character_Legend_Output_String.push_back(*Character_Legend_Pointer);
			Character_Legend_Output_String.insert(Character_Legend_Output_String.end(), 5, ' ');

		}

		//Check if the character value is a single digit value.
		if(Legend_Character_Value < 10){

			//Insert x number of spaces if the character value is a single digit value.
			Legend_Character_Value_Output_String += std::to_string(Legend_Character_Value) + "     ";

		//If the character value is NOT a single digit value.
		}else{

			//Insert (x number of spaces) - 1 if the character value is NOT a single digit value.
			Legend_Character_Value_Output_String += std::to_string(Legend_Character_Value) + "    ";

		}

		//Print 6 characters per line.
		if(Legend_Character_Value == 15 ||
		   Legend_Character_Value == 31){

			//Print the group of 6 characters as well as the character values.
			std::cout << std::string(13, ' ') << Character_Legend_Output_String << std::endl;
			std::cout << std::string(13, ' ') << Legend_Character_Value_Output_String << "\n\n" << std::endl;

			//Clear the output strings.
			Character_Legend_Output_String.clear();
			Legend_Character_Value_Output_String.clear();

		}

		//Increase the character value.
		Legend_Character_Value++;

	}

	//Print the last group of characters and values.
	std::cout << std::string(13, ' ') << Character_Legend_Output_String << std::endl;
	std::cout << std::string(13, ' ') << Legend_Character_Value_Output_String << std::endl;

	//Advance the console with the remaining space.
	std::cout << std::string(12, '\n');

	//Print a line above the menu.
	std::cout << std::string(120, '_') << std::endl;

	//Build the screen menu according to access.
	Build_Menu(Creator_Access,
			   Admin_Access,
			   Leader_Access,
			   "Legend");

	//Prompt the user to choose a menu option.
	std::cout << "\nPlease choose a menu option:" << std::endl;

	//Get users input.
	std::cin >> User_Input;

	//Convert the users input to uppercase.
	Convert_To_Upper_Case(User_Input);

	//Only the Creator and Admin can go the the generate an OTP screen.
	if(User_Input == "H"){

		//Go to the home screen after this function's return.
		Go_To_Screen = "Home";

	}else if((Creator_Access ||
		Admin_Access) &&
		User_Input == "G"){

		//Go to the generate an OTP screen after this function's return.
		Go_To_Screen = "Generate";

	//Only the Creator and Admin and go to the view users screen.
	}else if((Creator_Access ||
			  Admin_Access) &&
			  User_Input == "V"){

		//Go to the view users screen after this function's return.
		Go_To_Screen = "Users";

	//Only the Creator, Admin, and Leader can go to the encode message screen.
	}else if((Creator_Access ||
			  Admin_Access ||
			  Leader_Access) &&
			  User_Input == "E"){

		//Go to the encode a message screen after this function's return.
		Go_To_Screen = "Encode";

	//Everyone can go to the decode screen.
	}else if(User_Input == "D"){

		//Go to the decode a message screen after this function's return.
		Go_To_Screen = "Decode";

	//Everyone can go to the character legend screen.
	}else if(User_Input == "L"){

		//Go to the character legend screen after this function's return.
		Go_To_Screen = "Legend";

	//Everyone can go to the info screen.
	}else if(User_Input == "I"){

		//Go to the info screen after this function's return.
		Go_To_Screen = "Info";

	//Everyone can logout.
	}else if(User_Input == "X"){

		//Prompt the user for logout confirmation.
		if(Show_Confirm_logout_Message()){
			//Logout and go to the login screen after this function's return.
			Creator_Access =
			Admin_Access =
			Leader_Access =
			User_Access = false;

		}

	}

}


The output:
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
       ________                    __                                           ________   _____________________  
       \______ \  _____   _______ |  | __  ____    ____    ______  ______       \_____  \  \__    ___/\______   \ 
        |    |  \ \__  \  \_  __ \|  |/ / /    \ _/ __ \  /  ___/ /  ___/        /   |   \   |    |    |     ___/ 
        |    `   \ / __ \_ |  | \/|    < |   |  \\  ___/  \___ \  \___ \        /    |    \  |    |    |    |     
       /_______  /(____  / |__|   |__|_ \|___|  / \___  >/____  >/____  > ______\_______  /  |____|    |____|     
               \/      \/              \/     \/      \/      \/      \/ /_____/        \/                        
________________________________________________________________________________________________________________________
Access: Creator | Screen: Character Legend


             A     B     C     D     E     F     G     H     I     J     K     L     M     N     O     P     
             0     1     2     3     4     5     6     7     8     9     10    11    12    13    14    15    


             Q     R     S     T     U     V     W     X     Y     Z     0     1     2     3     4     5     
             16    17    18    19    20    21    22    23    24    25    26    27    28    29    30    31    


             6     7     8     9     !     @     #     $     %     &     +     =     :     '     .     SPACE
             32    33    34    35    36    37    38    39    40    41    42    43    44    45    46    47    












________________________________________________________________________________________________________________________
(H) Home | (G)-Generate OTP | (V)-View Users | (E)-Encode Message | (D)-Decode Message | (I)-Info | (X)-Logout

Please choose a menu option:
If using iterator, then auto is your friend. Also don't forget about .cbegin() and .cend(). See my example above.

PS. Although using meaningful names is great, having very long names also IMO makes the code more difficult to read! Some names are 36 chars long. I would suggest names no longer than about 15 chars to be meaningful and readable. Also don't forget that you have to type in these names every time they're used without any typing mistakes!
Topic archived. No new replies allowed.