1
123 Michael
456 Calimlim
898 Mykfyy
999 Kyxy
657 mykfyy
898 Help

I'm creating a student attendance keeper system. One of the features of my system is that the student need to register(his/her id and name) first to access the system (login with his/her id)

The problem is that i don't know and i don't want my student to have a similar ID number Like(e.g 898 Mykfyy and 898 Help)

I'm using fstream in my system. I've been thinking that if I want to avoid the duplication i need to Read(ifstream) the .txt file before register(oustream). But i dont know how to read line by line and check if the ID(898) is already use/existed

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
Michael
  • 31
  • 1
  • 3
    Please don't post text as pictures. Post text as text. – Swordfish Apr 25 '19 at 15:09
  • sorry about that, this is my first time posting a question with pictures~ thanks – Michael Apr 25 '19 at 15:12
  • Can't you just create the ID as an incremental number instead of allowing the user to pick an ID#? That would be easy and not require searching. It would just require you to know how many lines you have in your file (which is less than 10 lines of code). – drescherjm Apr 25 '19 at 15:23

3 Answers3

2

In C++ one wouldn't deal with lines, but with objects:

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

struct student_t
{
    unsigned id;
    std::string name;
};

bool operator==(student_t const &lhs, student_t const &rhs)
{
    return lhs.id == rhs.id;
}

std::ostream& operator<<(std::ostream &os, student_t const &student)
{
    return os << student.id << ' ' << student.name;
}

std::istream& operator>>(std::istream &is, student_t &student)
{
    unsigned id;
    if (!(is >> id))
        return is;

    std::string name;
    if (!std::getline(is, name)) {
        return is;
    }

    student = student_t{ id, name };
    return is;
}

int main()
{
    char const *filename{ "test.txt" };
    std::ifstream input{ filename };
    if (!input.is_open()) {
        std::cerr << "Couldn't open \"" << filename << "\" for reading :(\n\n";
        return EXIT_FAILURE;
    }

    std::vector<student_t> students{ std::istream_iterator<student_t>{ input }, std::istream_iterator<student_t>{} };
    input.close();

    std::copy(students.begin(), students.end(), std::ostream_iterator<student_t>{ std::cout, "\n" });

    student_t new_student;  
    while (std::cout << "New Student?\n", !(std::cin >> new_student)) {
        std::cerr << "Input error :(\n\n";
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }

    auto it{ std::find(students.begin(), students.end(), new_student) };
    if (it != students.end()) {
        std::cerr << "Sorry, but a student with id " << new_student.id << " already exists :(\n\n";
        return EXIT_FAILURE;
    }

    std::ofstream output{ filename, std::ios::app };
    if (!output.is_open()) {
        std::cerr << "Couldn't open \"" << filename << "\" for writing :(\n\n";
        return EXIT_FAILURE;
    }

    output << new_student << '\n';
    std::cout << "New student [" << new_student << "] added :)\n\n";
}

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • 1
    If the file is large `std::unsorted_map` may be a good alternative for `std::vector`. – user4581301 Apr 25 '19 at 15:34
  • Fork. I always do that and throw apostrophes into possessive "its". At least `unordered_map` has only been mocking me for a few years. "its" has been on my back for decades. – user4581301 Apr 25 '19 at 17:23
1

The easiest way to do it is probably using std::getline to get the current line as a string:

using namespace std;
ifstream in(fileName);

string line;
while(getline(in, line))
{
    // --do something with the line--
}

You will then need to parse each line to get the correct ID

Edit: updated to remove eof()

0

Depends on how you implemented it.

I suppose the number of people isn't too large so I would just check the Id's before a new ID is added.

Something like If ID exists, not add.