1

I have a text file. I have a text file consisting of member data. I am developing a program where we can get the member data from the file. After searching in the internet, I have searched a way to read all the data from the file as char array. But I want to change it where upon reading from file I want the data to be string and also integer.

  1. name, icno, email, phone_number, acc_num, password ( read from file AS STRING )
  2. month, year ( read from file AS INTEGER )

Content of Membership.txt

Mathavan|021127100897|MathavanKrishnan27@gmail.com|0167750575|1410065449|Mathavan1234|3|2022
Mathavan|021127100897|MathavanKrishnan27@gmail.com|0167750575|1410065448|Mathavan1234|3|2024
Mathavan|021127100897|MathavanKrishnan27@gmail.com|0167750575|1410065447|Mathavan1234|3|2022
string member_login(){
    title();
    fstream member;
    member.open("Membership.txt",ios::in);
    string pass_input, line, acc_num1, password1;
    int login_attempt = 0, count = 0 , account = 0;
    char dummy, resp, accno_input[25], name[25], icno[25],email [40], phone_number[25],acc_num[25],password[25],month[25], year[25];

    account_num:
    cout << "                                          Enter your account number : ";
    cin >> accno_input;

    ifstream file("Membership.txt");
    while (!file.eof()){
        getline(file, line);
        count++;
     }

    cout << accno_input;
    int i = 0;
    while(i <= count)
    {
        member.getline(name,25,'|');
        member.getline(icno,25,'|');
        member.getline(email,40,'|');
        member.getline(phone_number,25, '|');
        member.getline(acc_num,25, '|');
        member.getline(password,25,'|' );
        member.getline(month,25,'|' );
        member.getline(year, 25);

        cout << name << " ";
        cout << icno << " ";
        cout << acc_num << " ";
        cout << accno_input;

        if (acc_num == accno_input){
            account = 1;
            break;
        }

        i ++;
    }

    cout << account;

    member.close();

    if ( account != 1 ){
        cout << endl;
        cout << "                                  Your account not found !!!"<< endl;
        cout << "                                  Please try again !!" << endl << endl;
        cout << "                                  PLEASE ENTER ANY KEY TO CONTINUE >>> ";
        cin >> dummy;
        goto account_num;
    }

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

    for (login_attempt = 1 ; login_attempt <= 2 ; login_attempt ++){
        if (pass_input == password1){
            cout << "Login Successful !!!";
            break;
        }

        cout << endl;
        cout << "Login Failed. Attempt " << login_attempt  << " of 3" << endl;
        cout << "Please re-enter Password: " ;
        cin >> pass_input;

        if (pass_input == password1){
            cout << "Login Successful !!!";
                break;
        }
    }

    if ( login_attempt == 3){
        cout << endl;
        cout << "Login Failed. Attempt 3 of 3";
    }

    return accno_input;
}
  • 1
    What is your question? – Scott Hunter Oct 14 '21 at 17:45
  • FYI, your class should model a record (text line) of data. Your class should also overload `operator>>` to read its members from the file (or any stream). – Thomas Matthews Oct 14 '21 at 17:47
  • Handy reading (because it will help you with a bug you likely haven't seen yet): [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – user4581301 Oct 14 '21 at 17:51
  • @ScottHunter My question is currently I am getting all the data from file as char array. Now I want to change my coding abit where first 6 i want to read as string and the last two i want to read it as integer. – Mathavan Krishnan Oct 14 '21 at 17:56
  • To convert month and year from std::string to a number use std::stoul (stoul = **st**ring to **u**nsigned **l**ong) – Pepijn Kramer Oct 14 '21 at 18:03
  • Side note: the `25` in `member.getline(name,25,'|');` is what we call a [magic number](https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad). Among other problems, this opens you up to changing one use of the number and not others. For example, if the size of `name` is reduced without also reducing `25`, the program risks buffer overflow. – user4581301 Oct 14 '21 at 18:37

1 Answers1

0

There are so many things completely wrong in your program that I do recomend to you:

Delete and start from scratch.

There is no meaningful fix possible. There is even a goto. And you MUST stop using C-Style arrays with some agic dimension in C++. And C++ has many things to make your live easier. Simply use them.

Please find below a C++ solution.

You can copy and paste it and stay as you are, or, you take 3 hours and google all constructs and try to understand and learn and become a better programmer. Your choise.

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

const std::regex re{ R"(\|)" };

struct Member {
    // Memeber data
    std::string name{};
    std::string icno{};
    std::string email{};
    std::string phoneNumber{};
    std::string accountNumber{};
    std::string password{};
    int month{};
    int year{};

    // Extractor operator
    friend std::istream& operator >> (std::istream& is, Member& m) {

        // Readone complete line
        if (std::string line{}; std::getline(is, line)) {

            // Split it into parts
            std::vector parts(std::sregex_token_iterator(line.begin(), line.end(), re, -1), {});

            // assign parts to member data
            if (parts.size() == 8) {
                m.name = parts[0]; m.icno = parts[1]; m.email = parts[2]; m.phoneNumber = parts[3]; m.accountNumber = parts[4]; m.password = parts[5];
                m.month = std::stoi(parts[6]); m.year = std::stoi(parts[7]);
            }
        }
        return is;
    }
};

// Filename for member data
const std::string fileName{ "r:\\Membership.txt" };

int main() {
    // Open the data file and check, if it could be opened
    if (std::ifstream fileStream{ fileName }; fileStream) {

        // Read complete source file, parse it and get all data
        std::vector memberData(std::istream_iterator<Member>(fileStream), {});

        // We want the user to give 3 trials to enter valid data
        constexpr unsigned int MaxTrials = 3u;
        unsigned int numberOfTrials{}; 

        // A valid input will stop the loop immediately
        bool validInputgiven{};

        // Now, try to get the correct input
        while (not validInputgiven and numberOfTrials < MaxTrials) {

            // Get an acoount number
            std::cout << "\nEnter a account number: ";
            std::string account{};
            std::cin >> account;

            // Check, if the account number is in the member data
            if (std::count_if(memberData.begin(), memberData.end(), [&](const Member& m) { return m.accountNumber == account; }) > 0) {

                // Account info wasOK. Get the password
                std::cout << "\nEnter your password: ";
                std::string password{};
                std::cin >> password;

                if (std::count_if(memberData.begin(), memberData.end(), [&](const Member& m) { return m.accountNumber == account and m.password == password; }) > 0) {
                    // Valid data found
                    validInputgiven = true;
                    std::cout << "\n\nEverything OK. Data validated.\n\n";
                }
            }
            // Next try
            ++numberOfTrials;

            if (not validInputgiven and numberOfTrials < MaxTrials) std::cout << "\nInvalid input. Please try again\n\n\n";
        }
        if (not validInputgiven ) std::cout << "\nToo many wrong tries. Aborting . . .\n\n\n";
    }
    else std::cerr << "\n\nError. Could not open source file '" << fileName << "'\n\n";
}
A M
  • 14,694
  • 5
  • 19
  • 44