Messed up files...


Basically, I am trying to make a personal diary in which there are three profiles:

1.Admin
2.User
3.New User

The program reads and writes the administrator password correctly.

But when the user (after registering in the newuser profile) tries to login. The program is able to find his id, but it is unable to recognise the password.







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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<conio.h>
#include<string>
using namespace std;

class Admin{

public:
Admin(){




}

void Read(){

}

void Write(){


}

};

class NewUser{

public:
    string password,id,trys;
string menu(){
cout<<"Please give an id\n";

cin>>id;

cout<<"Please give your password\n"<<id<<endl;
//password="";
char c = ' ';
password="";
while(c != 13)  
   {
   c = getch();
   if(c!=13){
   password += c;
   cout << "*";}
   }

trys=password;
return trys;

}
string returns(){
return trys;
}

};

class User{

public:

char id[10], password[20];
void Read(){

}

void Write(){


}

void menu(){

cout<<"Please select your menu\n";
int m;
cin>>m;

switch(m){
case 1:

    Read();

    break;

case 2:

    Write();

    break;

default:

    cout<<"wrong option\n";
}
}
};

void CheckingPrimaryFiles(){

ifstream ifs("user.txt",ios::binary);

if(!ifs)
{

    ofstream of("user.txt",ios::binary|ios::app);
    of.close();
}

ifs.close();

ifstream a("Admin.txt");
if(!a){
    ofstream asd("Admin.txt");
    cout<<"FIRST TIME EXECUTION:\nPlease set a password\n";
    //char password[20],test[20];
    string password = "";
char c = ' ';

while(c != 13)  
   {
   c = getch();
   if(c!=13){
   password += c;
   cout << "*";}
   }
   asd<<password;

    asd.close();
}
a.close();
}


int PasswordChecker(int a,string password,string id){
//char p[20],test[20];
ifstream ifs("Admin.txt");
ifstream obj("user.txt",ios::binary);
//string pass = "";
NewUser am;
if(a==0){
    int i=0;
    string check;
    ifs>>check;
    cout<<check;
    if(check==password){
    return 1;
    ifs.close();}
else{
    return 0;
    ifs.close();}

}

else
{

    cout<<endl<<id<<" "<<password;
    while(!obj.eof()){
        obj.read((char*)&am, sizeof(NewUser));
        cout<<"\nrun\n"<<am.id<<endl;
        if(id==am.id){
            //cout<<"enter password\n";
            cout<<"Id reached\n";
              if(password==am.returns())
                 {  cout<<"password correct";
                     return 1;

                 }else{
                     string temp=am.returns();
                     cout<<"I am here\n"<<temp;
                    return 0;

                 }

                //cout<<pass<<" and "<<us.password;
        }else
        continue;

    }

}
//cout<<pass;
obj.close();
return 0;
}

int getPassword(int a,string id=""){
    cout<<"Please enter your password\n";
     //char password[20],test[20];
    string password = "";
char c = ' ';

while(c != 13) 
   {
   c = getch();
   if(c!=13){
   password += c;
   cout << "*";}
   }


      if(PasswordChecker(a,password,id))
           return 1;
      else
      return 0;
}

int main(){

    CheckingPrimaryFiles();
    string id;
    cout<<"Please choose profile\n";
    int profile;
    cin>>profile;
    switch(profile){
    //admin
case 1:

    cout<<"Please give the password\n";
    if(getPassword(0)){
            cout<<"Welcome Tanmay\n";
        Admin admin;

    }
    else
        cout<<"wrong password\n";
        break;
    //User
case 2:

    cout<<"Please provide id\n";


   cin>>id;
    if(getPassword(profile,id)){
        User user;
        user.menu();

    }else
    cout<<"wrong id and password\n";
    break;
    //New user
case 3:
//cout<<"Please give your id \n";
ofstream n;
n.open("user.txt",ios::app|ios::binary);

NewUser newuser;
newuser.menu();

n.write((char*)&newuser,sizeof(NewUser));

n.close();

    }

return 0;
}


Also my output is:
Please choose profile
2
Please provide id
100
Please enter your password
******
100 police
run (this is because it also prints the password and id. So that I can check whether it is working or not..)

        á☼  ♦ ♦ ♂☺♂ ♠    ☺   police SERPR♥ ♦ ↨☺♂              d  ♥ n s ╕☺> ╕☺> a
jumdar WATCOM=C:\watcom windir=D:\WINDOWS       → ☺   Σ♦
                                                                ►►►►►►►►►►►►►►►►
►►►►►►►►►►                                               ► ► ►                ►
                               ►►►►►►►►►►►►►►►►►►►►►►► ►►►►►►►

abcdefghijklmnopqrstuvwxyz      ABCDEFGHIJKLMNOPQRSTUVWXYZ        â      Ü £ ₧
         è î Ä           ¬          ╡    ║     αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷ °∙·√ⁿ²■▀└
┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓ ╪┘┌█▄▌▐ƒ   ► E  É*> ╨*>  +> @+> Ç+> ¿+> ╪+> °+> ►,> P,> x
,> ÿ,> ░,> `-> ¿-> ╨->  .> @.> `.> ê.> ¿.> └.> α.> ►/> @/> h/> É/> ╨/> ≡/>     ►
 ╖☺♀ ALLUSERSPROFILE=D:\Documents and Settings\All Users
 APPDATA=D:\Documents and Settings\Tanmay Majumdar\Application Data      ♦
 CLIENTNAME=Console      ♦ ü☺☼ CommonProgramFiles=D:\Program Files\Common Files
        ë☺♀ COMPUTERNAME=TANMAYMAJUMDAR     ♠ ♣ Æ☺♀ ComSpec=D:\WINDOWS\system32\
cmd.exe     ♦ ♠ £☺♀ FP_NO_HOST_CHECK=NO     ♥ ♦ ÿ☺♂ HOMEDRIVE=D:   ♥ g☺☼ HOMEPAT
H=\Documents and Settings\Tanmay Majumdar         o☺♂ LOGONSERVER=\\TANMAYMAJUMD
AR    ♦ ♣ h☺     NUMBER_OF_PROCESSORS=2  ♥ ♦ t☺
 OS=Windows_NT   ▬ ♥ s☺  Path=.;E:\CodeBlocks\MinGW\bin;E:\CodeBlocks\MinGW;D:\P
rogram Files\Common Files\Microsoft Shared\Windows Live;D:\WINDOWS\system32;D:\W
INDOWS;D:\WINDOWS\system32\wbem          ▬ M☺☼ PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;
 PROCESSOR_ARCHITECTURE=x86              R☺
 ♣ _☺♀ PROCESSOR_IDENTIFIER=x86 Family 15 Model 6 Stepping 5, GenuineIntel     ♦

 PROCESSOR_LEVEL=15      ♦ ♦  PROCESSOR_REVISION=0605 ♣ ♦ -☺
 ProgramFiles=D:\Program Files   ♦ ♣ 6☺♀ SESSIONNAME=Console     ♥ ♦ 2☺  SystemD
rive=D:  ♦ ♥ 1☺
 SystemRoot=D:\WINDOWS   ♠ ♦  TEMP=D:\DOCUME~1\TANMAY~1\LOCALS~1\Temp ♠ ♠ ☺
 TMP=D:\DOCUME~1\TANMAY~1\LOCALS~1\Temp  ♣ ♠ ☺☺♫ USERDOMAIN=TANMAYMAJUMDAR
 ♣ ♣
☺☼ USERNAME=Tanmay Majumdar       ♣ ↨☺
 USERPROFILE=D:\Documents and Settings\Tanmay Majumdar    ▼☺☼ WATCOM=C:\watcom
      ♦ ♦ ←☺♫ windir=D:\WINDOWS ♥  ►  ☺☺♦  Çⁿ┼wáⁿ┼w└ⁿ┼wαⁿ┼w ²┼w ²┼w@²┼w`²┼wDz┼wá
²┼w└²┼wα²┼w ■┼w ■┼w@■┼w`■┼wÇ■┼wá■┼w└■┼wα■┼w
























           A ☺☺ <'> \'> <'> $8> ─'> $8> $8> ñ'> $8> ─'> ä'> ─'>





                                                ╜ A  ►  x☺> x☺>


ps: Dont laugh at me :p
Last edited on
You cannot read or write NewUser as binary due to the complex type string. You can assume that string contains pointer.

So you write the value of the pointer and not what the point to (the text).
Next time you read the pointer value which is invalid and will likely lead to crash
So how can I fix this. Is there any alternative? using a character array will also cause the same problem.
And how is it able to read the id then, The problem is with the password only.
Last edited on
using a character array will also cause the same problem.
No it won't. Character array is not a pointer and will be written correctly.
Although I would advise against writing and reading blobs of data using read() like you do: adding another members or even compiling it on another compiler or on same compiler with different settings can break compatibility with current saves. Create your own serialization scheme (or use boost::serialization) to save data. That will have added benefit with correct working with inheritance as well.

And how is it able to read the id then
Did you use Visual studio? I know that it maintains small char buffer in addition to pointer to the rest of the data as small string optimization. It might be the case.

This is not so much in connection with your error but more of advice.

There are several flaws in your design, what happens if you have multiple users or want more than one admin, you are just creating an object of the same name on 238 and it will overwrite the previous one each time.

It is not necessary to have a separate class for New User, Admin and User, why not create a Class called User, have a Enum setup for User type and have a pointer to a second class to hold users diary entries, something like my example below.

With your objects of type CUser in a vector, you can search / sort etc. listing all admins, all users with no entries, users with entries and more. This would give you a lot more power.

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

// user types
enum USER_TYPE {
	NEW_USER,
	USER,
	ADMINISTRATOR
};

class CUser
{
private:
	unsigned char accType;  // admin, new user or whatever..
	int accId;  // a number you can assign to this account
	std::string accName;  // accounts name
	std::string accPassword;  // accounts password

	// pointer to users entry log
	CEntries *accEntries;

public:
	CUser();
	~CUser();

	// public functions for user account
	unsigned char getAccountType();
	void setAccountType(unsigned char);
	std::string getPassword();
	void setPassword(std::string);
	// user diary entries
	CEntries getEntry(int entry);
	
	// ... and so on

};

CUser::CUser()
{
	// some blank data for new objects
	accType = NEW_USER;
	accId = 0;
	accName.clear();
	accPassword.clear();
}

// and so on....


using a character array will also cause the same problem.

Why do you say this? The characteristics and behaviour of a simple array is very different to that of a std::string. Consider this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    char first[]       = "hippopotamus";
    std::string second = "hippopotamus";
    
    cout << "length of first string:  " << strlen(first) << endl;
    cout << "length of second string: " << second.size() << endl;
    
    cout << "size of char array:  " << sizeof(first) << endl; 
    cout << "size of std::string: " << sizeof(second) << endl; 
    
   return 0;
}

Output:

length of first string:  12
length of second string: 12
size of char array:  13
size of std::string: 4

Note: the actual output may vary depending upon the compiler and how the std::string is implemented internally.

Though the two strings are the same, the objects which contain them are very different. The char array contains the actual text including the null terminator. On the other hand the std::string uses a pointer to the actual data which is in some other part of memory.
Last edited on
using a character array will also cause the same problem.


I was saying this, because I was facing the same problem.
I copied the contents of the string in char array. Then in the PasswordChecker(), I compared that password string with the array of NewUser class.

But I am actually getting the same output.

@softrix:
Thanks for the tip, but the problem is, I am only a 11th grade student. I havent learnt about pointers and vectors yet. I am sure ill learn them in the future. But I am helpless right now,


Also multiple admins is not my idea.
But as
 user.txt
is a binary file, it will be able to hold multiple users.
After that I am gonna make separate text files for them , which will basically act as their diaries.

@minipaa:
I use codeblocks 12.11


NewCode:

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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<conio.h>
#include<string>
using namespace std;

class Admin{

public:
Admin(){




}

void Read(){

}

void Write(){


}

};

class NewUser{

public:
    string password,id,trys;
    char p[20];
void menu(){
cout<<"Please give an id\n";

cin>>id;

cout<<"Please give your password\n"<<id<<endl;
//password="";
char c = ' ';
password="";
while(c != 13)
   {
   c = getch();
   if(c!=13){
   password += c;
   cout << "*";}
   }

int length=password.length();
int l2=password.copy(p,length,0);
p[l2]='\0';
cout<<"the new user class "<<p;

}
string returns(){
return trys;
}

};

class User{

public:

char id[10], password[20];
void Read(){

}

void Write(){


}

void menu(){

cout<<"Please select your menu\n";
int m;
cin>>m;

switch(m){
case 1:

    Read();

    break;

case 2:

    Write();

    break;

default:

    cout<<"wrong option\n";
}
}
};

void CheckingPrimaryFiles(){

ifstream ifs("user.txt",ios::binary);

if(!ifs)
{

    ofstream of("user.txt",ios::binary|ios::app);
    of.close();
}

ifs.close();

ifstream a("Admin.txt");
if(!a){
    ofstream asd("Admin.txt");
    cout<<"FIRST TIME EXECUTION:\nPlease set a password\n";
    //char password[20],test[20];
    string password = "";
char c = ' ';

while(c != 13)
   {
   c = getch();
   if(c!=13){
   password += c;
   cout << "*";}
   }
   asd<<password;

    asd.close();
}
a.close();
}


int PasswordChecker(int a,string password,string id){
//char p[20],test[20];
ifstream ifs("Admin.txt");
ifstream obj("user.txt",ios::binary);
//string pass = "";
NewUser am;
if(a==0){
    int i=0;
    string check;
    ifs>>check;
    cout<<check;
    if(check==password){
    return 1;
    ifs.close();}
else{
    return 0;
    ifs.close();}

}

else
{

    cout<<endl<<id<<" "<<password;
    while(!obj.eof()){
        obj.read((char*)&am, sizeof(NewUser));
        cout<<"\nrun\n"<<am.id<<endl;
        if(id==am.id){
            //cout<<"enter password\n";
            cout<<"Id reached\n";
              if(password==am.p)
                 {  cout<<"password correct";
                     return 1;

                 }else{
                     string temp=am.p;
                     cout<<"I am here\n"<<temp;
                    return 0;

                 }

                //cout<<pass<<" and "<<us.password;
        }else
        continue;

    }

}
//cout<<pass;
obj.close();
return 0;
}

int getPassword(int a,string id=""){
    cout<<"Please enter your password\n";
     //char password[20],test[20];
    string password = "";
char c = ' ';

while(c != 13)
   {
   c = getch();
   if(c!=13){
   password += c;
   cout << "*";}
   }


      if(PasswordChecker(a,password,id))
           return 1;
      else
      return 0;
}

int main(){

    CheckingPrimaryFiles();
    string id;
    cout<<"Please choose profile\n";
    int profile;
    cin>>profile;
    switch(profile){
    //admin
case 1:

    cout<<"Please give the password\n";
    if(getPassword(0)){
            cout<<"Welcome Tanmay\n";
        Admin admin;

    }
    else
        cout<<"wrong password\n";
        break;
    //User
case 2:

    cout<<"Please provide id\n";


   cin>>id;
    if(getPassword(profile,id)){
        User user;
        user.menu();

    }else
    cout<<"wrong id and password\n";
    break;
    //New user
case 3:
//cout<<"Please give your id \n";
ofstream n;
n.open("user.txt",ios::app|ios::binary);

NewUser newuser;
newuser.menu();

n.write((char*)&newuser,sizeof(NewUser));

n.close();

    }

return 0;
}
Last edited on
id==am.id And you are still reading std::string from file.

I want to ask you, did you changed file you are reading from after you changed your program? Because any change to your classes would invalidate your file.

And second: remember, any complex class (basically anything from standard library and anything aside from POD structs) is not compatible with .read() method. At all. Even if it seems to work.
how long will you persist in banging your own head against the wall like this:

n.write((char*)&newuser,sizeof(NewUser));

Note that class NewUser contains member variables of type std::string so this cannot work.


Okay so I made a character array for the id as well. And know this thing finally works...

Thank you guys..

@Chervil:
Sorry, I actually did not know any other ways to save strings and as you can see my program consists of lots of strings. So I had no other alternative.
I did not know that write() cannot be used for strings.

Last edited on
Topic archived. No new replies allowed.