This is driving me nuts.

I'm writing a password program that reads from .txt file into an array of char arrays, and then allows the user to write a new password and then appends it to the end of the list.

Everything SEEMS to be working except everytime I run the program with existing passwords in the the .txt file and then save it, it adds a newline.

Here's my program minuys the functions that don't touch fstream or the lastIndex (my counter for existing passwords) - the problem seems to be in the initialization, new entry or write functions. I can't pin it down and have no clue why its doing this. Can someone please help me, I feel like my brain is gonna explode

// ****** MAIN ***************************************************
int main()
{
    char entries[100][16] = {'\0'};
    int lastIndex = 0;

    initialize(entries,  lastIndex);
    mainMenu(entries, lastIndex);
    return 0;
}



/* ------ FUNCTION: Initialize -----------------------------------
----------------------------------------------------------------*/
void initialize(char entries[][16], int &lastIndex)
{
    ifstream iFile("password.txt");
    iFile.close();


    char buffer[16] = {'\0'};
    int i = 0;
    if(!iFile)
    {
        ofstream oFile("password.txt");
        oFile.close();


    }
    else
    {

        iFile.open("password.txt");
        int r = 0;
        int c = 0;

        while(!iFile.eof() && buffer[0] != '\n')
        {
            if(iFile.eof()) break;

            iFile >> buffer;
            c = 0;
            while(buffer[c] != '\0' && buffer[0] != '\n')
            {
                if(iFile.eof()) break;
                entries[r][c] = buffer[c];
                entries[r][c + 1] = '\0';
                c++;

            }
            r++;
            i++;
        }
    }

        iFile.close();
        lastIndex = i;


}

/* ------ FUNCTION: WRITE PASSWORD -------------------------------
----------------------------------------------------------------*/
void writePassword(char entries[][16], int &lastIndex)
{
    ofstream oFile("password.txt");

    for(int i = 0; i < lastIndex; i++)
    {
        oFile << entries[i] << endl;

    }

    cout << "\n\nNew Password Successfully Written\n\n";

    mainMenu(entries, lastIndex);

}


/* ------ FUNCTION: NEW ENTRY ------------------------------------
----------------------------------------------------------------*/
void newEntry(char entries[][16], int &lastIndex)
{
    char buffer[256];
    char password[16];
    bool val[5];
    bool validation = true;

    for(int i = 0; i < 3; i++)
    {
        val[i] = true;
    }
   int length = 0;

    cin.getline(buffer,256);

    val[0] = valLength(buffer, password, length);
    val[1] = valUpper(password, length);
    val[2] = valLower(password, length);
    val[3] = valNum(password, length);
    val[4] = valChar(password, length);


    for(int i = 0; i < 5; i++)
    {
        if(val[i] == false)
        {
            validation = false;
        }
    }

    while(validation == false)
    {

        validation = true;
        cout << "\n\nPlease enter your new password: ";
        cin.getline(buffer,256);

        length = 0;
        val[0] = valLength(buffer, password, length);
        val[1] = valUpper(password, length);
        val[2] = valLower(password, length);
        val[3] = valNum(password, length);
        val[4] = valChar(password, length);


       for(int i = 0; i < 5; i++)
        {
            if(val[i] == false)
            {
                validation = false;
            }
        }
    }
    int c = 0;
    while(password[c] != '\0')
    {
        entries[lastIndex][c] = password[c];
        c++;
    }
    entries[lastIndex][length] = '\0';
    lastIndex++;

    writePassword(entries, lastIndex);



    return;
}


/* ------ FUNCTION: DISPLAY --------------------------------------
----------------------------------------------------------------*/
void display(char entries[][16], int &lastIndex)
{
    cout << "\n"<<lastIndex<<"\n";
    if(lastIndex <= 0)
    {
        cout << "No Entries";
    }
    else
    {

        for(int i = 0; i < lastIndex; i++)
        {
            cout << entries[i] << endl;
        }
    }
    cout << "\n\n";
    mainMenu(entries, lastIndex);
}

Example:
Please choose 1, 2, or 3.
1. Save a new password
2. Display all passwords
3. Exit

Choose 1, 2, or 3: 2

4
Password1
Password2
Password3

Please choose 1, 2, or 3.
1. Save a new password
2. Display all passwords
3. Exit

Choose 1, 2, or 3: 1

------ New Entry ------------------------

Please enter your new password: Password4

New Password Successfully Written

Please choose 1, 2, or 3.
1. Save a new password
2. Display all passwords
3. Exit

Choose 1, 2, or 3: 2

5
Password1
Password2
Password3

Password4

Please choose 1, 2, or 3.
1. Save a new password
2. Display all passwords
3. Exit

Choose 1, 2, or 3: 1

------ New Entry ------------------------

Please enter your new password: Password5

New Password Successfully Written

Please choose 1, 2, or 3.
1. Save a new password
2. Display all passwords
3. Exit

Choose 1, 2, or 3: 2

6
Password1
Password2
Password3

Password4
Password5

Please choose 1, 2, or 3.
1. Save a new password
2. Display all passwords
3. Exit

Choose 1, 2, or 3:

Edited 2 Years Ago by Jjajangmyeon

You might be confused by using endl. It probably would be more accurate to call it newl. It tells the file to start a new line. To eliminate that only write the new line to the second last line:

void writePassword(char entries[][16], int &lastIndex)
{
    ofstream oFile("password.txt");
    int i = 0;
    for(; i < lastIndex - 1; i++)
    {
        oFile << entries[i] << endl;
    }
    oFile << entries[i];
    cout << "\n\nNew Password Successfully Written\n\n";
    mainMenu(entries, lastIndex);
}

On a side note, since you use the same validation routine in more than one place, it would make sense to split that off into a function. If the rules you use to validate a password change you'll only have to modify one routine.

Also, when you use eof() to check for the end of the file, your routine will have to run an extra time. Using the actual extraction statement means that the loop will exit as soon as the extraction fails:

while(iFile >> buffer)
{        
    c = 0;
    while(buffer[c] != '\0')
    {
        entries[r][c] = buffer[c];
        entries[r][c + 1] = '\0';
        c++;
    }
    r++;
    i++;
}

Edited 2 Years Ago by tinstaafl

This question has already been answered. Start a new discussion instead.