1

currently I have a information.txt file with a list of residents and their unit number such as A-1-1 and A-1-2. I am having difficulty when I wish to allow my program to add user to its own unit number but limited to a situation where 1 unit maximum can have 2 residents registered in a single unit.

It is possible to code my program to read the unit number in the information.txt file and only allow the user to register themselves in the program when their unit is not fully registered (maximum 2 resident per unit)?

This is my university programming assignment...I am just a beginner...This is so far what I have...Please help me with this...Hope you can understand my situation.

void add_new_user(void)
{   
    system("CLS");
    ifstream in_file ("information.txt");
    USER new_user[40];
    int index=0;
    char option;
    char unit_number;
    if(!in_file)
    {
        cout << "Error opening txt file" << endl;
        
    }
    else
    {
        USER U_list[MAX_USER];
        int index = 0;
        
        fflush (stdin);
        in_file.getline(U_list[++index].unit_number, LENGTH_UNIT);
        while (in_file)
        {
            in_file.getline(U_list[index].name, LENGTH_NAME);
            in_file.getline(U_list[index].email, LENGTH_MAIL);
            in_file.getline(U_list[index].phone, MAX_NUM);
            in_file.getline(U_list[index].IC, LENGTH_IC); 
                
            if(in_file.peek() == '\n')
                in_file.ignore(256, '\n');
            
            in_file.getline(U_list[++index].unit_number,LENGTH_UNIT); 
        }
        in_file.close();
        
        bool in = false;
        
        do
        {
        char check_unit_number[LENGTH_UNIT];
        int unit_number_count = 0;
        cout << "==================================================" << endl;
        cout << "==\tUser Management System\t\t==" << endl;
        cout << "==================================================" << endl;
        cout << "==\tAdd New User\t\t\t==" << endl;
        cout << "==================================================\n";
        
        fflush(stdin);
        cout << "\nEnter unit number of the new user: " <<endl; 
        cin.get(check_unit_number, LENGTH_UNIT);
        cin.ignore();
        
            for (int i =1; i < index; i++)
                if (strcmp(check_unit_number,U_list[i].unit_number) == 0)
                unit_number = i;
                                

                if (strcmp(check_unit_number,U_list[unit_number].unit_number) == 0)
                {
                    fflush(stdin);
                    cout << "\nEnter new user's unit number: " << endl;
                    cin.get(new_user[++index].unit_number, LENGTH_UNIT);
                    cin.clear();
        
                    fflush(stdin);
                    cout << "\nEnter new user's name: " << endl;
                    cin.get(new_user[index].name, LENGTH_NAME);
                    cin.clear();

                    fflush(stdin);
                    cout << "\nEnter new user's EMAIL ADDRESS: " << endl;
                    cin.get(new_user[index].email, LENGTH_MAIL);
                    cin.clear();
                    
                    fflush(stdin);
                    cout << "\nEnter new user's phone number: " << endl;
                    cin.get(new_user[index].phone, MAX_NUM);
                    cin.clear();
                
                    fflush(stdin);
                    cout << "\nEnter new user's IC: " << endl;
                    cin.get(new_user[index].IC, LENGTH_IC);
                    cin.clear();  
                
                    do
                    {
                            cout << "\nDo you confirm to register this new user? [Yes - Y, No - N]\n=>";
                            cin >> option;
                            
                            if(option != 'Y' && option != 'N' && option != 'y' && option != 'n')
                            {
                                cout << endl;
                                cout << "Wrong input. Enter again." << endl;
                                cout << endl;
                            }
                        }while(option != 'Y' && option != 'N' && option != 'y' && option != 'n');   
        
                        if(option=='Y' || option=='y')
                        {
                            ofstream out_file ( "information.txt", ios :: app); 
                            out_file << setiosflags (ios :: left) << new_user[index].unit_number << endl;
                            out_file << setiosflags (ios :: left) << new_user[index].name << endl;
                            out_file << setiosflags (ios :: left) << new_user[index].email << endl;
                            out_file << setiosflags (ios :: left) << new_user[index].phone << endl;
                            out_file << setiosflags (ios :: left) << new_user[index].IC << endl;
                    
                            out_file.close();
                            cout << endl;
                            cout << "The new user is successfully registered.\n" << endl;
                            system ("pause");
                            return;
                        }
                    
                        else if(option=='N' || option=='n')
                        {
                            cout << "\nThe new user is not registered.\n" << endl;
                            system ("pause");
                            return;
                        }
                }
                    else if (strcmp(check_unit_number,U_list[unit_number].unit_number) != 0) 
                    {
                        cout << "\nThis unit number is not exist.\n" << endl;
                        system ("pause");
                        return;
                    }
        }while(!in);
    }
}
KokWei
  • 11
  • 1
  • 4
    Fyi, burn whatever reference told you `fflush(stdin);` is viable. [It invokes *undefined behavior*](https://stackoverflow.com/questions/5810410/alternative-for-fflushstdin). Just saying. – WhozCraig Aug 21 '21 at 09:37
  • 1
    "_and their unit number such as A-1-1_" and the variable `char unit_number;` will not work well. The variable is only capable of storing _one_ `char` and `A-1-1` requires six (including the null terminator). Suggestion: Make a `unit` class first and figure out how to serialize that. – Ted Lyngmo Aug 21 '21 at 09:37
  • How to make a unit class? – KokWei Aug 21 '21 at 09:46
  • @KokWei Does a _unit_ always contain one `char` and two non-negative integers? If so, `struct unit { char letter; unsigned a; unsigned b; };` could be a start. You would then usually add the free (non-member) functions `std::istream& operator>>(std::istream&, unit&);` and `std::ostream& operator<<(std::ostream&, const unit&);` to do the streaming. – Ted Lyngmo Aug 21 '21 at 09:54

1 Answers1

1

You have some basic problems in understanding IO operations.

You need to check the difference between formatted and unformatted input. For example std::cin >> option; will read one character, but not the '\n' at the end of the line. A subsequent call to an unformatted input function, will read just the '\n' and nothing more.

Then, you are mixing up std::istream.get() and std::istream.getline(). They have a total different behaviour regarding the handling of the "end of line" character '\n'. Please read here and here.

You need to understand the difference.

Then, many additional problems resulting from using plain C-Style arrays and especially not standard C-elements like std::string. If you would use std::string then life would be very much simpler.

Anyway, there are many other more syntax and semantic errors, as well as design errors.

Important notice: Please make your design first on a piece of paper and then start coding. Always think many days, before writing the first line of code.

So, then to your code. Lets make it compilable:

#include <iostream>
#include <fstream>
#include <iomanip>

#include <stdlib.h>
#include <string.h>

using namespace std;

#define MAX_USER 100
#define LENGTH_UNIT 30
#define LENGTH_NAME 50
#define LENGTH_MAIL 80
#define MAX_NUM 35
#define LENGTH_IC 50

struct USER {
    char unit_number[LENGTH_UNIT];
    char name[LENGTH_NAME];
    char email[LENGTH_MAIL];
    char phone[MAX_NUM];
    char IC[LENGTH_IC];
};

void add_new_user(void)
{
    system("CLS");
    ifstream in_file("information.txt");
    USER new_user[40];
    int index = 0;
    char option;
    char unit_number;
    if (!in_file)
    {
        cout << "Error opening txt file" << endl;

    }
    else
    {
        USER U_list[MAX_USER];
        int index = 0;

        fflush(stdin);
        in_file.getline(U_list[++index].unit_number, LENGTH_UNIT);
        while (in_file)
        {
            in_file.getline(U_list[index].name, LENGTH_NAME);
            in_file.getline(U_list[index].email, LENGTH_MAIL);
            in_file.getline(U_list[index].phone, MAX_NUM);
            in_file.getline(U_list[index].IC, LENGTH_IC);

            if (in_file.peek() == '\n')
                in_file.ignore(256, '\n');

            in_file.getline(U_list[++index].unit_number, LENGTH_UNIT);
        }
        in_file.close();

        bool in = false;

        do
        {
            char check_unit_number[LENGTH_UNIT];
            int unit_number_count = 0;
            cout << "==================================================" << endl;
            cout << "==\tUser Management System\t\t==" << endl;
            cout << "==================================================" << endl;
            cout << "==\tAdd New User\t\t\t==" << endl;
            cout << "==================================================\n";

            fflush(stdin);
            cout << "\nEnter unit number of the new user: " << endl;
            cin.get(check_unit_number, LENGTH_UNIT);
            cin.ignore();

            for (int i = 1; i < index; i++)
                if (strcmp(check_unit_number, U_list[i].unit_number) == 0)
                    unit_number = i;


            if (strcmp(check_unit_number, U_list[unit_number].unit_number) == 0)
            {
                fflush(stdin);
                cout << "\nEnter new user's unit number: " << endl;
                cin.get(new_user[++index].unit_number, LENGTH_UNIT);
                cin.clear();

                fflush(stdin);
                cout << "\nEnter new user's name: " << endl;
                cin.get(new_user[index].name, LENGTH_NAME);
                cin.clear();

                fflush(stdin);
                cout << "\nEnter new user's EMAIL ADDRESS: " << endl;
                cin.get(new_user[index].email, LENGTH_MAIL);
                cin.clear();

                fflush(stdin);
                cout << "\nEnter new user's phone number: " << endl;
                cin.get(new_user[index].phone, MAX_NUM);
                cin.clear();

                fflush(stdin);
                cout << "\nEnter new user's IC: " << endl;
                cin.get(new_user[index].IC, LENGTH_IC);
                cin.clear();

                do
                {
                    cout << "\nDo you confirm to register this new user? [Yes - Y, No - N]\n=>";
                    cin >> option;

                    if (option != 'Y' && option != 'N' && option != 'y' && option != 'n')
                    {
                        cout << endl;
                        cout << "Wrong input. Enter again." << endl;
                        cout << endl;
                    }
                } while (option != 'Y' && option != 'N' && option != 'y' && option != 'n');

                if (option == 'Y' || option == 'y')
                {
                    ofstream out_file("information.txt", ios::app);
                    out_file << setiosflags(ios::left) << new_user[index].unit_number << endl;
                    out_file << setiosflags(ios::left) << new_user[index].name << endl;
                    out_file << setiosflags(ios::left) << new_user[index].email << endl;
                    out_file << setiosflags(ios::left) << new_user[index].phone << endl;
                    out_file << setiosflags(ios::left) << new_user[index].IC << endl;

                    out_file.close();
                    cout << endl;
                    cout << "The new user is successfully registered.\n" << endl;
                    system("pause");
                    return;
                }

                else if (option == 'N' || option == 'n')
                {
                    cout << "\nThe new user is not registered.\n" << endl;
                    system("pause");
                    return;
                }
            }
            else if (strcmp(check_unit_number, U_list[unit_number].unit_number) != 0)
            {
                cout << "\nThis unit number is not exist.\n" << endl;
                system("pause");
                return;
            }
        } while (!in);
    }
}
int main() {
    add_new_user();
}

So, now it is at least compilable. However, it will not work. There are still compiler warnings:

enter image description here

All errors and warnings must be removed.

Let us start with refactoring.

First a code review. I put all finding as a comment in the source code.

Note: Nearly every line of code has a finding.

#include <iostream>
#include <fstream>
#include <iomanip>

#include <stdlib.h>         // Do not use C headers
#include <string.h>         // Do not use C headers

using namespace std;        // Should never be done in C++. Always use qualified names

#define MAX_USER 100        // Macros should never be used for that purpose in C++. Use constexpr instead
#define LENGTH_UNIT 30      // Macros should never be used for that purpose in C++. Use constexpr instead
#define LENGTH_NAME 50      // Macros should never be used for that purpose in C++. Use constexpr instead
#define LENGTH_MAIL 80      // Macros should never be used for that purpose in C++. Use constexpr instead
#define MAX_NUM 35          // Macros should never be used for that purpose in C++. Use constexpr instead
#define LENGTH_IC 50        // Macros should never be used for that purpose in C++. Use constexpr instead

struct USER {
    char unit_number[LENGTH_UNIT];  // C-Style arrays should not be used in C++. Use datatype string instead
    char name[LENGTH_NAME];// C-Style arrays should not be used in C++. Use datatype string instead
    char email[LENGTH_MAIL];// C-Style arrays should not be used in C++. Use datatype string instead
    char phone[MAX_NUM];// C-Style arrays should not be used in C++. Use datatype string instead
    char IC[LENGTH_IC];// C-Style arrays should not be used in C++. Use datatype string instead
};

void add_new_user(void)
{
    system("CLS");             // Should not be used
    ifstream in_file("r:\\information.txt");
    static USER new_user[40];  // Do not put this onto the functions stack.  Why 40? No need to collect new users locally
    // int index = 0;          // index is defined again below
    char option;
    unsigned int unit_number;  // Should not be char but unsigned int
    if (!in_file)
    {
        cout << "Error opening txt file" << endl;   // Should be written do std::cerr. endl not necesarry

    }
    else
    {
        static USER U_list[MAX_USER]; // Should not be put onto stack of function
        int index = 0;               // Should be unsigned

        fflush(stdin);                // Should never be done. Will end in undefined behaviour

        in_file.getline(U_list[++index].unit_number, LENGTH_UNIT);  // Should be optimized
        while (in_file)
        {
            in_file.getline(U_list[index].name, LENGTH_NAME);
            in_file.getline(U_list[index].email, LENGTH_MAIL);
            in_file.getline(U_list[index].phone, MAX_NUM);
            in_file.getline(U_list[index].IC, LENGTH_IC);

            if (in_file.peek() == '\n')                             // Why that?
                in_file.ignore(256, '\n');

            in_file.getline(U_list[++index].unit_number, LENGTH_UNIT);  // Bad index handling
        }

        in_file.close(); // No need. Destructor will close file for you. But, does not harm

        bool in = false;  // Starting an endless loop and jumping out with return. Bad design
        do
        {
            char check_unit_number[LENGTH_UNIT];// C-Style arrays should not be used in C++. Use datatype string instead
            // int unit_number_count = 0;   This variable is used nowhere          // endl not necessary. \n can be part of string
            cout << "==================================================" << endl; // endl ist not necessary. All the following can be done in one statement.
            cout << "==\tUser Management System\t\t==" << endl;
            cout << "==================================================" << endl;
            cout << "==\tAdd New User\t\t\t==" << endl;
            cout << "==================================================\n";

            fflush(stdin);   // Should never be done. Will end in undefined behaviour
            cout << "\nEnter unit number of the new user: " << endl;  // endl not necessary. \n can be part of string
            cin.get(check_unit_number, LENGTH_UNIT);
            cin.ignore();     // ???

            for (int i = 0; i < index; i++)  // array indices start with 0 in c++
                if (strcmp(check_unit_number, U_list[i].unit_number) == 0)
                    unit_number = i;     // **** This will result in undefined and bad behaviour
            // Because, unit number may never be initialized and that it has an undefined (random) value
            // Or the value from the last loop run. In any case: wrong

            if (strcmp(check_unit_number, U_list[unit_number].unit_number) == 0)   // **** May leed to out of bounds undefined beahviour
            {
                fflush(stdin);  // Should never be done. Will end in undefined behaviour
                cout << "\nEnter new user's unit number: " << endl;     // endl not necessary. \n can be part of string
                cin.get(new_user[++index].unit_number, LENGTH_UNIT);
                cin.clear();   // Better handling of errors necessary

                fflush(stdin);      // Should never be done. Will end in undefined behaviour
                cout << "\nEnter new user's name: " << endl;    // endl not necessary. \n can be part of string
                cin.get(new_user[index].name, LENGTH_NAME);
                cin.clear();    // Better handling of errors necessary

                fflush(stdin);      // Should never be done. Will end in undefined behaviour
                cout << "\nEnter new user's EMAIL ADDRESS: " << endl;   // endl not necessary. \n can be part of string
                cin.get(new_user[index].email, LENGTH_MAIL);
                cin.clear();    // Better handling of errors necessary

                fflush(stdin);      // Should never be done. Will end in undefined behaviour
                cout << "\nEnter new user's phone number: " << endl;    // endl not necessary. \n can be part of string
                cin.get(new_user[index].phone, MAX_NUM);
                cin.clear();    // Better handling of errors necessary

                fflush(stdin);      // Should never be done. Will end in undefined behaviour
                cout << "\nEnter new user's IC: " << endl;  // endl not necessary. \n can be part of string
                cin.get(new_user[index].IC, LENGTH_IC);
                cin.clear();    // Better handling of errors necessary

                do
                {
                    cout << "\nDo you confirm to register this new user? [Yes - Y, No - N]\n=>";
                    cin >> option;

                    if (option != 'Y' && option != 'N' && option != 'y' && option != 'n')
                    {
                        cout << endl;   // endl not necessary. \n can be part of string
                        cout << "Wrong input. Enter again." << endl;   // endl not necessary. \n can be part of string
                        cout << endl;    // endl not necessary. \n can be part of string
                    }
                } while (option != 'Y' && option != 'N' && option != 'y' && option != 'n');

                if (option == 'Y' || option == 'y')
                {
                    ofstream out_file("information.txt", ios::app);
                    out_file << setiosflags(ios::left) << new_user[index].unit_number << endl;
                    out_file << setiosflags(ios::left) << new_user[index].name << endl;
                    out_file << setiosflags(ios::left) << new_user[index].email << endl;
                    out_file << setiosflags(ios::left) << new_user[index].phone << endl;
                    out_file << setiosflags(ios::left) << new_user[index].IC << endl;

                    out_file.close();
                    cout << endl;  // endl not necessary. \n can be part of string
                    cout << "The new user is successfully registered.\n" << endl;   // endl not necessary. \n can be part of string
                    system("pause");   // Should not be used
                    return;    // Like a goto. Bad design
                }

                else if (option == 'N' || option == 'n')
                {
                    cout << "\nThe new user is not registered.\n" << endl;    // endl not necessary. \n can be part of string
                    system("pause");   // Should not be used
                    return; // Like a goto. Bad design
                }
            }
            else if (strcmp(check_unit_number, U_list[unit_number].unit_number) != 0)
            {
                cout << "\nThis unit number is not exist.\n" << endl;    // endl not necessary. \n can be part of string
                system("pause");    // Should not be used
                return;        // Like a goto.Bad design
            }
        } while (!in); // Using an endless loop and jumping out with return. Bad design
    }
}
int main() {
    add_new_user();
}

Next. Let's remove the hard bugs and the findings. Much better. But: The result will still not work as expected:


#include <iostream>
#include <fstream>
#include <iomanip>

#include <stdlib.h>
#include <string.h>

constexpr unsigned int MAX_USER = 100;
constexpr unsigned int LENGTH_UNIT = 30;
constexpr unsigned int LENGTH_NAME = 50;
constexpr unsigned int LENGTH_MAIL = 80;
constexpr unsigned int MAX_NUM = 35;
constexpr unsigned int LENGTH_IC = 50;

struct USER {
    char unit_number[LENGTH_UNIT];      
    char name[LENGTH_NAME];             
    char email[LENGTH_MAIL];            
    char phone[MAX_NUM];                
    char IC[LENGTH_IC];                 
};

void add_new_user(void)
{
    std::ifstream in_file("r:\\information.txt");

    if (!in_file)
    {
        std::cerr << "\n\n*** Error opening source txt file\n\n";
    }
    else
    {
        static USER U_list[MAX_USER]; // Should not be put onto stack of function
        int index = 0;               // Should be unsigned

        while (in_file)
        {
            in_file.getline(U_list[index].unit_number, LENGTH_UNIT);  // Should be optimized
            in_file.getline(U_list[index].name, LENGTH_NAME);
            in_file.getline(U_list[index].email, LENGTH_MAIL);
            in_file.getline(U_list[index].phone, MAX_NUM);
            in_file.getline(U_list[index].IC, LENGTH_IC);
            ++index;
        }

        in_file.close();

        bool in = false;
        do
        {
            std::cout << "==================================================\n"
                << "==\tUser Management System\t\t==\n"
                << "==================================================\n"
                << "==\tAdd New User\t\t\t==\n"
                << "==================================================\n";

            std::cout << "\nEnter unit number of the new user:\n";
            USER new_user{};
            std::cin.getline(new_user.unit_number, LENGTH_UNIT);

            // We want to count, how many of these units are already in
            unsigned int unitCounter = 0;

            // Search the unit number that was entered by the user in the list of existing users read from the file
            for (int i = 0; i < index; i++) {
                if (std::strcmp(new_user.unit_number, U_list[i].unit_number) == 0) {
                    ++unitCounter;
                }
            }
            // If this units exists
            if (unitCounter == 1)
            {
                std::cout << "\nEnter new user's name:\n";
                std::cin.getline(new_user.name, LENGTH_NAME);

                std::cout << "\nEnter new user's EMAIL ADDRESS:\n";
                std::cin.getline(new_user.email, LENGTH_MAIL);

                std::cout << "\nEnter new user's phone number:\n";
                std::cin.getline(new_user.phone, MAX_NUM);

                std::cout << "\nEnter new user's IC:\n";
                std::cin.getline(new_user.IC, LENGTH_IC);

                char option{};
                do
                {
                    std::cout << "\nDo you confirm to register this new user? [Yes - Y, No - N]\n=>";
                    std::cin >> option;

                    if (option != 'Y' && option != 'N' && option != 'y' && option != 'n')
                    {
                        std::cout << "\nWrong input. Enter again.\n\n";
                    }
                } while (option != 'Y' && option != 'N' && option != 'y' && option != 'n');

                if (option == 'Y' || option == 'y')
                {
                    std::ofstream out_file("r:\\information.txt", std::ios::app);
                    out_file << std::left << new_user.unit_number << '\n';
                    out_file << new_user.name << '\n';
                    out_file << new_user.email << '\n';
                    out_file << new_user.phone << '\n';
                    out_file << new_user.IC << std::endl;

                    out_file.close();

                    std::cout << "\nThe new user is successfully registered.\n\n";
                    in = true;
                }

                else if (option == 'N' || option == 'n')
                {
                    std::cout << "\nThe new user is not registered.\n\n";
                    in = true;
                }
            }
            else if (unitCounter == 0) {
                std::cout << "\n\nError Unit does not exist\n\n";
                in = true;
            }
            else if (unitCounter >= 1) {  // For 2 and more
                std::cout << "\n\nError. Max 2 residents per unit\n\n";
                in = true;
            }
         } while (!in); 
    }
}
int main() {
    add_new_user();
}


Now, add a little bit minimum C++. Still keep the nasty char arrays instead of strings.

But, this solution will work already.

#include <iostream>
#include <fstream>
#include <iomanip>

#include <stdlib.h>
#include <string.h>

constexpr unsigned int MAX_USER = 100;
constexpr unsigned int LENGTH_UNIT = 30;
constexpr unsigned int LENGTH_NAME = 50;
constexpr unsigned int LENGTH_MAIL = 80;
constexpr unsigned int MAX_NUM = 35;
constexpr unsigned int LENGTH_IC = 50;

struct USER {
    char unit_number[LENGTH_UNIT];
    char name[LENGTH_NAME];
    char email[LENGTH_MAIL];
    char phone[MAX_NUM];
    char IC[LENGTH_IC];

    friend std::istream& operator >> (std::istream& is, USER& u) {
        is.getline(u.unit_number, LENGTH_UNIT);
        is.getline(u.name, LENGTH_NAME);
        is.getline(u.email, LENGTH_MAIL);
        is.getline(u.phone, MAX_NUM);
        return  is.getline(u.IC, LENGTH_IC);
    }
    friend std::ostream& operator << (std::ostream& os, const USER& u) {
        return os << u.unit_number << '\n' << u.name << '\n' << u.email << '\n' << u.phone << '\n' << u.IC << std::endl;
    }
};
struct DataBase {
    USER U_list[MAX_USER]{};
    unsigned int numberOfUserInDatabase{};

    friend std::istream& operator >> (std::istream& is, DataBase& d) {
        while (is >> d.U_list[d.numberOfUserInDatabase])
            ++d.numberOfUserInDatabase;
        return is;
    }
 };

DataBase dataBase;

void add_new_user(void)
{
    std::ifstream in_file("r:\\information.txt");

    if (!in_file)
    {
        std::cerr << "\n\n*** Error opening source txt file\n\n";
    }
    else
    {

        in_file >> dataBase;
        in_file.close();

        bool in = false;
        do
        {
            std::cout << "==================================================\n"
                << "==\tUser Management System\t\t==\n"
                << "==================================================\n"
                << "==\tAdd New User\t\t\t==\n"
                << "==================================================\n";

            std::cout << "\nEnter unit number of the new user:\n";
            USER new_user{};
            std::cin.getline(new_user.unit_number, LENGTH_UNIT);

            // We want to count, how many of these units are already in
            unsigned int unitCounter = 0;

            // Search the unit number that was entered by the user in the list of existing users read from the file
            for (unsigned int i = 0; i < dataBase.numberOfUserInDatabase; i++) {
                if (std::strcmp(new_user.unit_number, dataBase.U_list[i].unit_number) == 0) {
                    ++unitCounter;
                }
            }
            // If this units exists
            if (unitCounter == 1)
            {
                std::cout << "\nEnter new user's name:\n";
                std::cin.getline(new_user.name, LENGTH_NAME);

                std::cout << "\nEnter new user's EMAIL ADDRESS:\n";
                std::cin.getline(new_user.email, LENGTH_MAIL);

                std::cout << "\nEnter new user's phone number:\n";
                std::cin.getline(new_user.phone, MAX_NUM);

                std::cout << "\nEnter new user's IC:\n";
                std::cin.getline(new_user.IC, LENGTH_IC);

                char option{};
                do
                {
                    std::cout << "\nDo you confirm to register this new user? [Yes - Y, No - N]\n=>";
                    std::cin >> option;

                    if (option != 'Y' && option != 'N' && option != 'y' && option != 'n')
                    {
                        std::cout << "\nWrong input. Enter again.\n\n";
                    }
                } while (option != 'Y' && option != 'N' && option != 'y' && option != 'n');

                if (option == 'Y' || option == 'y')
                {
                    std::ofstream out_file("r:\\information.txt", std::ios::app);
                    out_file << new_user;

                    out_file.close();

                    std::cout << "\nThe new user is successfully registered.\n\n";
                    in = true;
                }

                else if (option == 'N' || option == 'n')
                {
                    std::cout << "\nThe new user is not registered.\n\n";
                    in = true;
                }
            }
            else if (unitCounter == 0) {
                std::cout << "\n\nError Unit does not exist\n\n";
                in = true;
            }
            else if (unitCounter >= 1) {  // For 2 and more
                std::cout << "\n\nError. Not more than max 2 residents per unit allowed\n\n";
                in = true;
            }
        } while (!in);
    }
}



int main() {
    add_new_user();
}


And last but not least: Remove all C code. And make it an advanced C++ solution.

This will be too complicated in the beginning, but can show the way to go:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

// Here all unit/user data will be stored
const std::string userDataBaseFileName{ "information.txt"};

// CLass for one user
class User {
     // User data
    std::string unit{};
    std::string name{};
    std::string email{};
    std::string phoneNumber{};
    std::string IC{};
public:

    // IO functions. Extractor operator
    friend std::istream& operator >> (std::istream& is, User& u) {
        std::getline(is, u.unit);
        std::getline(is, u.name);
        std::getline(is, u.email);
        std::getline(is, u.phoneNumber);
        return  std::getline(is, u.IC);
    }
    // Inserter operator
    friend std::ostream& operator << (std::ostream& os, const User& u) {
        return os << u.unit << '\n' << u.name << '\n' << u.email << '\n' << u.phoneNumber << '\n' << u.IC << std::endl;
    }
    // Check, if 2 units are equal
    bool equalUnit(const User& other) const { return unit == other.unit; }

};

// IO functions. Extractor operator

class DataBase {
    std::vector<User> user{};
public:
    // Here is the number of maximum users per unit
    static constexpr size_t MaxUserPerUnit{ 2u };
    static_assert(MaxUserPerUnit >= 1 , "Error: At least one user must be allowed per Unit\n"); // Must be greater than 1

    // Calculate number of user per unit
    size_t usersInUnit(const User& testUser) const { return std::count_if(user.begin(), user.end(), [&](const User& u) { return u.equalUnit(testUser); }); }

    // IO functions. Extractor operator. Read all users
    friend std::istream& operator >> (std::istream& is, DataBase& d) {
        User tempUser{}; 
        while (is >> tempUser) d += tempUser;
        return is;
    }
    // Inserter operator
    friend std::ostream& operator << (std::ostream& os, const DataBase& u) {
        std::copy(u.user.begin(), u.user.end(), std::ostream_iterator<User>(os));
        return os;
    }
    // Ad a new use to the database via += operator
    DataBase& operator+=(const User& u) {
        if (usersInUnit(u) < MaxUserPerUnit)
            user.push_back(u);
        else 
            std::cerr << "Error. Too many users in unit. Ignoring user:\n" << u << "\n\n";
        return *this;
    }

};

DataBase dataBase;

void addNewUser()
{
    // Open source file and chek, if it could be opened
    if (std::ifstream informationDataFileStream{ userDataBaseFileName }; informationDataFileStream) {

        // The file is open. Read all data from file
        informationDataFileStream >> dataBase;

        // Some debug output
        std::cout << "\n\nThe following data has been read from file:\n\n" << dataBase << "\n\n";

        // Ask operator to enter a new user
        std::cout << "\nPlease enter new user information. One at a line. In this order: Unit, Name, Email, Phone Number, ID:\n";

        // Read a new user from operator
        User tempUser{}; std::cin >> tempUser;

        // Confirm, if the user wants really add this info.
        std::cout << "\n\nYour entered the following data:\n\n" << tempUser << "\n\nDo you really want to add? (y = yes, everything else = No\n--> ";

        char option{}; std::cin >> option;
        if (option == 'y') {

            // Give confirmation to user
            std::cout << "\n\nData will be added to database\n";

            // add new user to database
            dataBase += tempUser;

            // Save all data to disk
            if (std::ofstream dataFileStream{ userDataBaseFileName }; dataFileStream) {
                dataFileStream << dataBase;
            }
            else std::cerr << "\nError: Could not open file '" << userDataBaseFileName << "' for writing\n\n";
        }
        else std::cout << "\n\nData will NOT be added to database\n";
    }
    else std::cerr << "\nError: Could not open file '" << userDataBaseFileName << "' for reading\n\n";
}

int main() {
    addNewUser();
}

Have fun . . .

A M
  • 14,694
  • 5
  • 19
  • 44