inconsistancy reading from file..

So this is my second week in c++ and just fooling around with no real motive just trying to become familiar with the language. Im writing a script that reads a file for a certain name and then spits out the password associated with it. the problem i'm having is that some of the lines are read with an extra character(aka one space or more too far), but others are read perfectly...
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
#include ...
using namespace std;
int main()
{
searchfile: {
string linen, lastuser="robert", linens, password;
char getlines[256];
char enter;
int count=0, countt=0, lgth=0, countn=0;
fstream myfile ("text docs/usernames.txt");
myfile.seekg (0, ios::end);
lgth = myfile.tellg();
myfile.seekg (0, ios::beg);
myfile >> linen;
myfile.getline(getlines, sizeof getlines, '\n') >> enter;
recheckfile:
{
if ((linen != lastuser) && (enter != '-') && (!myfile.eof())) {
    myfile.seekg(count);
    myfile >> linen;
    countn = (linen.length()+count);
    count = (countn+2);
    myfile.getline(getlines, sizeof getlines, '\n') >> enter;
    goto recheckfile;
}
else if (linen == lastuser) {
    cout << "user name found: " << linen;
    countt = myfile.tellg();
    myfile.seekg(countt);
    myfile >> password;
    cout << password;
}
else {
    cout << "username not found";
    }
}
}
}


txt doc is layed out like so
1
2
3
4
5
6
7
8
9
10
11
12
Dan
=
1
_
Billy
=
2
_
John
=
3
_


and so on; if i run the code as is(searching for "robert") it prints out what i would want it to(6 - robert's "password") but if i search for Billy it just gives me the =; and different all around(aka searching for Susan would give me the next username, i tried to create a check to see if it was because it had increased a count somewhere and offset it, but that didnt help
change:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
else if ((linen == lastuser) && (ifcount < 1)) {
    cout << "1 user name found: " << linen << "\n";
    countt = myfile.tellg();
    myfile.seekg(countt);
    myfile >> password;
    cout << password;
}
else if ((linen == lastuser) && (ifcount >= 1)) {
    cout << "2 user name found: " << linen << "\n";
    countt = myfile.tellg();
    myfile.seekg(countt-4);
    myfile >> password;
    cout << password;
}

still no consistency; What is it that im missing? please help!
First, I see you have defined the label searchfile, but do not use it. I personally refuse to use labels/goto because I don't believe it's proper. Secondly, you declared main as int, but return nothing. You also do not use the variable lgth.

One thing I noticed with running it is that the array you use to store the information all clashes together. I used "Dan" as the lastuser and got username Dan, password lly, the last three letters of the user Billy. I believe your concept of the fstream needs to be revised. Use an array for each line, or use a structure to house the username/password.
I've some what fixed the clashing of storage; it now returns, somewhat of what i expected, aka only that line; but i have 3 new errors
1. first line of text file is skipped; reads password for dan and not dan(first line)
2. rechecks the same object around 3 times, but not always the same checks passwords multiple times but not usernames
3. password returned is not the next line after correct username

text file layout
1
2
3
4
5
Usr1
usr1 pass
Usr2
usr 2 pass
.....


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
int main()
{
string linen, lastuser, passwords;
char password[256], glinens[256];
int count=0, coruntt=0, countn=0, sucessp=0; //all counters start at zero incase firstline is true
cout << "Please enter the user you're looking for: \n"; //answer sets lastuser
cin >> lastuser;
fstream myfile ("text docs/usernames.txt"); //opens usernames
myfile.getline(glinens, sizeof glinens, '\n') >> linen; //reads first line
myfile.close();
cout << linen << "\n";
recheckfile:
{
if ((linen != lastuser) && (!myfile.eof())) { // if lastuser isnt current line and not the end of the file
    fstream myfilef ("text docs/usernames.txt"); //opens usernames
    myfilef.seekg(count); //moves File pointer position to count, count increases after first loop, starts at 0
    cout << "Looking for: " << linen << "\n"; //for debugging
    countn = (linen.length()+count); //sets newcount to length of linen plus previous count; should start 0+ linen length
    count = countn;
    cout << "checked " << linen << "\n";//debugging
    myfilef.getline(glinens, sizeof glinens, '\n') >> linen; //reads next line
    sucessp = myfilef.tellg(); //sets sucessp incase next check is true
    myfilef.close();
    goto recheckfile; // rechecks for new linen
}
else if (linen == lastuser) { //if linen is lastuser
    cout << "User name found: " << linen << "\n"; // prints linen instead of lastuser incase linen changed somewhere
    coruntt = (sucessp+linen.length()); //sets corunttn to what should be pointer position at end of username
    fstream myfilet ("text docs/usernames.txt"); //opens usernames
    myfilet.seekg(coruntt); //sets pointer posistion to what should be password
    myfilet.getline(password, sizeof password, '\n') >> passwords; //reads and stores password
    myfilet.close();
    cout << "Password: " << passwords;
    return 0;
}
else {
    cout << "username not found";
    return 1;
    }
}
}
Last edited on
Should i just leave fstream myfile "open" through out it all or is there some logic behind closing it everytime(aka opens the file fresh everytime)?
I don't understand why you open the same file twice. I don't understand why you close it and reopen it either. And like I said before I don't like labels, and I personally feel it's a bad habit, maybe I'm wrong.

As for using the label, I'd suggest using a for loop, and your conditional statement should be while you're not at the end of the file. Let me see if I can make this work properly.

Do you have a copy of usernames that I can test?
I understand your dislike of labels/goto's; i find them somewhat useful in organization, but i probably use them too liberally where loops are more useful(as in this situation);
I only tried to open/close the file redundantly because in a previous code, i had an error reading and then trying to write so i just opened to read, and then opened to write, so i tried opening fresh to read in this instance, but that was useless;
as for the usernames file it's really simple, just plain info at the moment.
1
2
3
4
5
6
7
8
9
10
11
12
dan
1a
billy
2b
john
3c
susan
4d
reanan
5e
robert
6f

Thank you for you help


NOTE: i know that this is hardly secure for a password application, but is more for a reading/writing from learning experiment for me; my previous scripting/programming experience comes from mIRC scriptkidding(where my goto love comes from) around age 13; and bored in math on my TI83; Trying to get back in to computers for a career of some sort(recently A+ certified); trying to learn as much as i can everywhere starting with C+.
I remember coding on the graphing calculators. I was never "cool" enough to have one so I did everyone one better and designed the graphing calculator on the computer...plus their games they always had. But I'll get back to you in a bit.
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
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main() {
   string userName[10], userPass[10], lastUser;
   bool foundUser = false;
   
   fstream userFile;
   userFile.open("text docs/usernames.txt"); // Opens usernames
   if (!userFile.is_open()) { // Failed to open file
      cout << "File open failed!";
      return 0; // Exit program
   }
   
   for (int i = 0; !userFile.eof(); i ++) { // Loop til the end of file
      getline(userFile, userName[i]); // Store one line to userName
      getline(userFile, userPass[i]); // Store one line to userPass
   }
   
   userFile.close(); // Close file
   
   cout << "Please enter the user you're looking for: \n"; //answer sets lastuser
   cin >> lastUser;
   
   for (int i = 0; i < 10; i ++) // Loop through arrays
      if (lastUser == userName[i]) {
         cout << "User name " << lastUser << " found!\n";
         cout << "Password is: " << userPass[i];
         return 0;
      }
   
   cout << "User name " << lastUser << " not found!";
}


In my opinion this is much simpler than what you were trying to do. Unless I missed something...Just remember, the username IS case sensitive.
Now what if there are more than 10 user names in the file? it ends up giving an error. the usernames file is essentially dynamic in the sense that there will always be changes being made to it(that part i've worked out quite well)

thanks for all your help.
Then use vectors if you want truly dynamic. I just saw that your code was doing a lot more than it had to. The idea was good, but I don't think the implementation was quite as good. I don't think dealing with file pointers is the best way to do this, unless there is a point that I missed.
i figured out the problem it's really simple or at least i think i have; the problem wasnt in the type of variable the username and pass were, it was that you limited the search, so instead of counting up through the for, i decided to count down;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   for (int i = 0; !userFile.eof(); i ++) { // Loop til the end of file
      getline(userFile, userName[i]); // Store one line to userName
      getline(userFile, userPass[i]); // Store one line to userPass
   e++; //gives base for I in comparison
   }

   userFile.close(); // Close file

   for (int i=e; i > 1; i --) // Loop through arrays
     {
      if (lastuser == userName[i]) {
         cout << "User name " << lastuser << " found!\n";
         passchk = userPass[i];
         goto askpass;
      }
Topic archived. No new replies allowed.