fstream skips first character

Hi, I'm trying to create a login-window for my 1st code, but I've encountered a weird problem. The ofstream to file skips one character of my password-string.
Does anyone have any solutions for this?
Some words in the code may be in Norwegian.

Thank you in advance.

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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  //Written for use with C++ Windows-compiler

#include <iostream>
#include <string>
#include <sstream>
#include <chrono>
#include <thread>
#include <Windows.h>
#include <fstream>
#include <iomanip>
using namespace std;

void newscreen() {
	system("CLS");
	cout << "Huge amount of asterisks, removed for this forum";
	Sleep(500);
	system("CLS");
}


void main() {
	int oldnew;
	string oldusername;
	string username;
	string newpassword1;
	string newpassword2;
	int exitstart;
	char yesno_start;
	char y = 'y';
	char n = 'n';
	ifstream inFile;
	string filename;

	newscreen();

start: {
	system("CLS");

	cout << endl << endl << endl << endl;
	cout << "-------------LOGIN-------------";
	cout << endl << endl << endl;
	cout << "[1] existing user - [2] new user" << endl << endl;
	cin >> oldnew;


	if (oldnew == 1) {
		goto exisiting;
	}

	else if (oldnew == 2) {
		goto newuser;
	}

	else {
		cout << endl;
		cout << "Wrong value" << endl;
		goto start;
	}
	}


	
exisiting: {
	newscreen();

	inFile.open("C:\\Users\\straslak\\source\\repos\\LoginTest\\Debug\\passwords.txt");
	if (!inFile) {
		cout << "Unable to open file passwords.txt";
		Sleep(0500);
		filename = "passwords.txt";
		ofstream out(filename.c_str());
	
	}
	else {
		goto username1;
	}


	system("CLS");

username1:
	cout << endl << endl << endl;
	cout << "Enter username: ";
	cin.ignore();
	getline(cin, oldusername);

	if (oldusername.empty()) {
		cout << endl << endl;
		cout << "Not valied - enter a username" << endl;
		goto username1;
	}
	else {
		goto passordold;
	}


passordold:
	char password1[100];
	
	readfromfile:
	ifstream accountloggin;
	accountloggin.open("C:\\Users\\straslak\\source\\repos\\LoginTest\\Debug\\passwords.txt");
	accountloggin >> username >> newpassword1;

	Sleep(1000);

	cout << endl << endl << "Enter your password: ";
	cin >> password1;
	Sleep(200);

	if (username == oldusername) {
		if (password1 == newpassword1) {
			goto loggedin;
		}

		else {
			system("CLS");
			cout << "Wrong username or password" << endl << endl;
			Sleep(100);
			goto username1;
		}
	}
	else if (username != oldusername) {
		system("CLS");
		cout << "Wrong username or password" << endl << endl;
		Sleep(100);
		goto username1;
	}




loggedin:
	inFile.close();
	system("CLS");
	cout << "You've made it, woho!" << endl << endl;
	cout << "What do you want to do?" << endl;
	cout << "[1] Exit - [2] Back to start" << endl << endl;
	cin >> exitstart;

	if (exitstart == 1) {
		newscreen();
		Sleep(1000);
		system("CLS");
		exit(1);
	}
	else if (exitstart == 2){
		newscreen();
		Sleep(1000);
		system("CLS");
		goto start;
	}
	else {
		cout << "Not a valid option, chose again.";
		goto loggedin;
	}
}



newuser: {
	newscreen();

username2:
	system("CLS");
	cout << endl << endl << endl;
	cout << "Enter a username: ";
	cin.ignore();
	getline(cin, username);

	if (username.empty()) {
		cout << endl << endl;
		cout << "Not valied - enter a new username" << endl;
		goto username2;
	}

password2:
	cout << endl << endl;
	cout << "Enter your password: (press space before password) ";
	cin.ignore();
	getline(cin, newpassword1);
	cout << endl << endl;
	cout << "Please re-enter password: (press space before password) ";
	cin.ignore();
	getline(cin, newpassword2);

	if (newpassword1.empty()) {
		system("CLS");
		cout << endl << "The passwords is too short, try again!";
		goto password2;
	}

	else {

		if (newpassword1 == newpassword2) {
			goto loggedin_newuser;
		}

		else if (newpassword1 != newpassword2) {
			system("CLS");
			cout << endl << "The passwords does not match, try again!";
			goto password2;
		}
	}


loggedin_newuser:

	newscreen();

	ofstream account;
	account.open("C:\\Users\\straslak\\source\\repos\\LoginTest\\Debug\\passwords.txt", ios_base::app);
	account << username << " " << newpassword1 << "   ";
	account.close();


	system("CLS");
	cout << endl << endl << endl << endl << "--------You've logged in--------" << endl << endl;
	cout << "Go back to start? [y/n]" << endl;
	cin >> yesno_start;

	if (yesno_start == y) {
		goto start;
	}
	else {
		newscreen();
		system("CLS");
		exit(1);
	}


	}
return;
}

Hello straslak,

Welcome to the forum.

A few thing I see right off.

It is int main() not void along with return 0; at the end of main. void main() is old and outdated.

The use of "goto" statements is bad form and poor programming. You are making unconditional jumps around the program and could be missing something when you jump. It is also harder to figure out what is going on and where the program is going to.

Using using namespace std; may work now, but it WILL get you in trouble someday. It is best to learn to qualify what is in the standard namespace and qualify these items.

In the use of ofstream out(filename.c_str());, the ".cstr()" is not needed from C++11 on. A "std::string" will work fine.

This is a portion of your 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
loggedin:
	inFile.close();
	system("CLS");
	cout << "You've made it, woho!" << endl << endl;
	cout << "What do you want to do?" << endl;
	cout << "[1] Exit - [2] Back to start" << endl << endl;
	cin >> exitstart;

if (exitstart == 1) {
		newscreen();
		Sleep(1000);
		system("CLS");
		exit(1);
	}
	else if (exitstart == 2){
		newscreen();
		Sleep(1000);
		system("CLS");
		goto start;
	}
	else {
		cout << "Not a valid option, chose again.";
		goto loggedin;
	}
}

That is better written as:
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
loggedin:
		inFile.close();
		system("CLS");
		cout << "You've made it, woho!" << endl << endl;
		cout << "What do you want to do?" << endl;
		cout << "[1] Exit - [2] Back to start" << endl << endl;
		cin >> exitstart;

		if (exitstart == 1)
		{
			newscreen();
			Sleep(1000);
			system("CLS");
			exit(1);
		}
		else if (exitstart == 2)
		{
			newscreen();
			Sleep(1000);
			system("CLS");
			goto start;
		}
		else
		{
			cout << "Not a valid option, chose again.";
			goto loggedin;
		}
}

Except for the closing } on the last line having no opening { you can see how what is there makes the code easier to read. Technically there is nothing wrong with what you have done, but when the {}s line up in the same column it makes them easier to find especially when one is missing.

I will have to figure out an input file and test the program to figure out what is going wrong.

Hope that helps,

Andy
Hello straslak,

Found it.

The use of cin.ignore(); before the "getline" statements is unnecessary. cin.ignore(); should only follow something like cin >> aVariable. The reason is that cin >> aVariable leaves the newline character in the input buffer which needs to be removed before the use of a "getline" which will extract the new line and move on.

The more accepted way of using "ignore" is
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>. And if you will be using "Windows.h" you may need to write your header files as:

1
2
3
#include <Windows.h>
#undef max
#include <limits> 

This is what I found works for me with VS.

So, comment out or remove all the cin.ignore(); lines and the program will work better.

Since you are using "<iomanip>" you could do something like:
1
2
std::cout << std::setfill('*') << std::setw(200) << ' ' << std::endl;
std::cout << std::setfill(' ');

And adjust the 200 as needed or use a variable defined as a const.

"Sleep()" is specific to Windows and not able to be used by everyone. Something you could do is define a constant variable at the beginning of the program with a given value and then use sleep as Sleep(sleepTime);. This way you will only have one place to change if you need to change the time.

"system()" anything should be avoided at all times as it could leave your program vulnerable to attack.

I have a function for Windows that will clear the screen if you are interested.

Hope that helps,

Andy
Thank you for your help, Andy!
I tried your fix, and it worked!

No my problem is that it will only read the first string in my .txt-file, and thus I'm only able to save one "user".

It would be a blast if you had a fix for this as well! :D

Brg,
Aslak
Hello straslak,

I did not go that far, but I will look into it.

Andy
Hello straslak,

Notice line 8 of your original code only reads the file once with no way to repeat the read,, so you are only dealing with the first two entries of the file. Even though you have a label to go back to you never do and it would be in the wrong place. I have a fix for the problem, but even with that the code should be rewritten to eliminate the use of the "goto"statements.

I have put comments in my code to explain what was changed.

Your original 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
passordold:
	char password1[100];

readfromfile:

	ifstream accountloggin;
	accountloggin.open("C:\\Users\\straslak\\source\\repos\\LoginTest\\Debug\\passwords.txt");

	accountloggin >> username >> newpassword1;

	Sleep(1000);

	cout << endl << endl << "Enter your password: ";
	cin >> password1;

	Sleep(200);

	if (username == oldusername)
	{
		if (password1 == newpassword1)
		{  // <--- With only one line the {}s are nt needed.
			goto loggedin;
		}

		else
		{
			system("CLS");
			cout << "Wrong username or password" << endl << endl;
			Sleep(100);
			goto username1;
		}
	}
	else if (username != oldusername)
	{
		system("CLS");
		cout << "Wrong username or password" << endl << endl;
		Sleep(100);
		goto username1;
	}


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
passordold:
		  char password1[100];

	  readfromfile:
		  ifstream accountloggin;
		  //accountloggin.open("C:\\Users\\straslak\\source\\repos\\LoginTest\\Debug\\passwords.txt");
		  accountloggin.open("passwords.txt");  // <--- For my use. Switch comments for yur use.

		  Sleep(1000);  // <--- A pause here is not really needed.

		  cout << endl << endl << "Enter your password: ";  // <--- Moved next 3 lines up before while loop.
		  cin >> password1;
		  Sleep(200);

		  while (accountloggin >> username >> newpassword1)
		  {
			  if (username == oldusername)
			  {
				  if (password1 == newpassword1)
                                  //{
					  goto loggedin;
                                 //}

				  // <--- This part is never reached.
				  //else
				  //{
				  // system("CLS");
				  // cout << "Wrong username or password" << endl << endl;
				  // Sleep(100);
				  // //goto username1;
				  //}
			  }
		  }

		  //  else if has no matching if statement. It is not needed here and the following lines shloud unindent.
		  //else if (username != oldusername)  // <--- If you make it here, nothing in the file matched.
		  //{
                  //  <--- No longer needs indented as far.
		  system("CLS");
		  cout << "Wrong username or password" << endl << endl;
		  Sleep(100);
		  goto username1;
		  //} 


Left some of the code in with comments so you can see the difference of what is no longer needed.

Hope that helps,

Andy
Thank you, Andy! Your solution worked perfectly!

I'm now in the process of rewriting the code to eliminate all goto statements.

You've helped a lot! :)
Topic archived. No new replies allowed.