A question about string::iterator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Encode_Message(string User_Input, const string Legend){
	string Encoded_Message;
	string::iterator Char_Pointer;

	for(Char_Pointer = User_Input.begin(); Char_Pointer != User_Input.end(); Char_Pointer++){

		//Check if user input has leading or trailing spaces.
		if(*Char_Pointer == ' ' && (Char_Pointer != User_Input.begin() || Char_Pointer != User_Input.end())){


		}

	}
	return;

}


That's the code I'm working on right now. Is Char_Pointer an address to some value? If so *Char_Pointer is the value at address Char_Pointer?

Based on some testing this appears to be true, but this is not what I thought before now. I use iterators elsewhere in my code that had me thinking that Char_Pointer is a pointer.



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
//Classes:
class User_Data_Class{
	private:
		string Name;
		string Pass;
		string Access;

	public:
		User_Data_Class(string n, string p, string a) : Name(n), Pass(p), Access(a){};

		string Get_Name(){return Name;}
		string Get_Pass(){return Pass;}
		string Get_Access(){return Access;}

};


//Type Aliases:
using User_Data = vector <User_Data_Class>;


//Function Prototypes:
void Conv_To_Upper_Case(string&);
void Create_User_Access(User_Data&);
bool UserLogin(User_Data&, bool&, bool&, bool&, string&);
void Draw_Header_ASCII_Art();
void DrawMenu(bool, bool, string);
void Generate_OTP(const string, fstream&);
int Check_OTP(fstream&);
bool Display_Pop_Up_Msg(const string);
void Encode_Message(string, const string);

void Draw_Message_Characters_Left(int);
void Draw_Message_Missing_OTP();
void Draw_Message_Want_To_Encode();
void Draw_Message_Want_To_Decode();
void Draw_Message_Type_A_Message();


//Main Code #######################################################
int main(){

	//Objects created before access is granted
	bool User_Access = false;
	bool Admin_Access = false;
	bool Creator_Access = false;

	string Go_To_Page = "";

	User_Data User;





	//Assemble the user vector for user verification.
	Create_User_Access(User);





	//User Login
	if(UserLogin(User, User_Access, Admin_Access, Creator_Access, Go_To_Page)){

        }
return 1;

}


//FUNCTIONS ###############################################################
void Create_User_Access(User_Data &User){

	//Users to be added.
	User.emplace_back("c", "c", "Creator");
	User.emplace_back("c", "a", "Admin");
	User.emplace_back("c", "u", "User");
	User.emplace_back("CharlesR", "c123", "Creator");
	User.emplace_back("JudeC", "j123", "Admin");
	User.emplace_back("DaveM", "d123", "User");

}





bool UserLogin(User_Data &User, bool &User_Access, bool &Admin_Access, bool &Creator_Access, string &Go_To_Page){
	int Login_Attempts;
	string Name, Pass;
	User_Data::iterator User_Pointer;

	//The user has 3 attempts to log in.
	for(Login_Attempts = 3; Login_Attempts > 0; Login_Attempts--){

		//Ask for the user for their name.
		cout << string(50, '\n' ) << endl;
		cout << "                                               You must log in..." << endl;
		cout << string(20, '\n' ) << endl;
		cout << "Enter your user name:" << endl; //Ask for user's name
		cin >> Name;

		//Ask for the user for their password.
		cout << string(50, '\n' ) << endl;
		cout << "                                               You must log in..." << endl;
		cout << string(20, '\n' ) << endl;
		cout << "Enter your user password:" << endl;  //Ask for user's password
		cin >> Pass;

		//Find user via user input login credentials.
		for(User_Pointer = User.begin(); User_Pointer != User.end(); User_Pointer++){

			//Check user's name.
			if(User_Pointer->Get_Name() == Name){

				//Check user's password.
				if(User_Pointer->Get_Pass() == Pass){

					//User verified. Break to prevent further searching.
					break;

				}

			}

		}

		//Provide the user with access if the user was verified. If User_Pointer == User.end(), the user was not verified.
		if(User_Pointer != User.end()){

			//Provide the user with appropriate access.
			if(User_Pointer->Get_Access() == "User"){
				User_Access = true;
				Go_To_Page = "User_Home";

			}else if(User_Pointer->Get_Access() == "Admin"){
				Admin_Access = true;
				Go_To_Page = "Admin_Home";

			}else if(User_Pointer->Get_Access() == "Creator"){
				Creator_Access = true;
				Go_To_Page = "Creator_Home";

			}
			return true;

		}

	}
	return false;

}


This second code had me thinking the User_Pointer is a pointer, because to access the private methods of my class I had to use -> to do it. Is User_Pointer a pointer or an address?

This is all so confusing. All of this code works, I just want to know exactly what it all is to save time in the future when coding. I waste so much time trying to figure out why stuff doesn't work and it's all because im not understanding what it is im working with.
Last edited on
Iterators can be thought of as pointers, but in reality they are not pointers. They are custom types that have overloaded operators that allow it to ACT as if it were a pointer.
Hi,

Iterators do behave like pointers, and there are facilities in the STL to manipulate them:

https://en.cppreference.com/w/cpp/iterator/advance
https://en.cppreference.com/w/cpp/iterator

Note that if one is going from begin to end of a container, it's probably easier to use a range based for loop:

https://en.cppreference.com/w/cpp/language/range-for

This will save you a lot of time.

If you are going to use iterators, the use of auto makes the code easier. Let the compiler deduce the type of iterator.

Btw, there is no need of the return statement in your first code snippet. If one wants to finish a function early, then that's fine, but not at the end of a void function.

Is User_Pointer a pointer or an address?


Realise that a pointer is just a variable that holds an address in memory. User_Pointer is an iterator, but it behaves like a pointer in the same way as a reference does.
I didn't know that return wasn't needed for void funtions. Interesting. What's really interesting is that some of my void functions don't have returns and I don't know why I forgot them.

About the range based loops... aren't I using range based loops?

Thanks for the info everyone.
About the range based loops... aren't I using range based loops?


No. You're using iterator loops. Eg:

1
2
3
4
const std::string str {"abc"};

for (const auto ch : str)
    std::cout << ch;


This is a range-based for loop using the : to specify the iteration over what the range is taken. The part before the : specifies the type etc for each element obtained. After the : specifies the object to use.

See https://en.cppreference.com/w/cpp/language/range-for
Last edited on
Topic archived. No new replies allowed.