Как проверить, существует ли конкретное целочисленное значение, вводимое с клавиатуры, в строке или нескольких строках файла в C ++ - PullRequest
0 голосов
/ 20 октября 2019

У меня небольшой проект для курса C ++, и я застрял, пытаясь проверить, существует ли в файле значение члена класса STUDENT («ID»). Я попытался использовать какую-то функцию, которую нашел в Интернете, чтобы преобразовать целочисленное значение, которое я ищу, в строку, а затем использовать функцию поиска, чтобы найти ее в каждой строке файла.

Это работает, но всякий раз, когда я проверяю одну строку из файла, оно становится ложно-положительным, потому что значение идентификатора (например, «12»), например, идентично значению age (также «12»). Это происходит потому, что значение возраста предшествует значению идентификатора в моем файле, а также в строковой переменной (и я не могу его изменить). Я не знаю, чтобы искать в строке значение только ID. Я использую функцию «inputInfo» для ввода значений членов student1 с клавиатуры и функцию «checkID», чтобы проверить, существует ли уже значение «ID» в файле. Кроме того, для другого аспекта проекта я ищу способ поиска вхождения значений членов идентификатора и имени в один и тот же файл (после того, как они уже записаны). Одно из решений, которое я подумал, состоит в том, чтобы каким-то образом начать поиск после появления другого символа (например, символа пробела, учитывая тот факт, что в файле каждое поле отделено от другого пробелом), но я не уверенФункция поиска способна сделать это. Заранее благодарю за помощь. Ниже приведена часть кода проекта на C ++:

#include<iostream>
#include<string>
#include<fstream>
#include <sstream>

using namespace std;

int checkID(int idNumber)
{
    string findID;
    stringstream id_string;
    id_string << idNumber;
    findID = id_string.str();
    int offset;
    ifstream in;
    in.open("Students.txt");
    if(in.is_open())
    {
        string line;
        while(getline(in, line))
        {
            if(offset = line.find(findID, 0)!= string::npos)
            {
                cout<<"The ID already exists. Insert a different ID!"<<endl;
                return 0;
            }
        }

    }
    else
        cout<<"File doesn't exist!"<<endl;
    in.close();
}

class PERSON
{
protected:
    string name;
    string surname;
    unsigned int age;
public:
    void inputinfo()
    {
        cin>>name;
        cin>>surname;
        cin>>age;
    }
    outputinfo()
    {
        cout<<name<<endl;
        cout<<surname<<endl;
        cout<<age<<endl;
    }
};

class STUDENT: public PERSON
{
    int ID;
    float marks_sum;
    string belonging_class;

public:

    inputInfo()
    {
        cout<<"Name:";
        cin>>name;
        cout<<"Surname:";
        cin>>surname;
        cout<<"Age:";
        cin>>age;
        do
        {
            cout<<"ID:";
            cin>>ID;
        }
        while (checkID(ID)==0);

        cout<<"Sum of marks:";
        cin>>marks_sum;
        cout<<"The belonging class:";
        cin>>belonging_class;

    }


    void outputInfo()
    {
        cout<<name<<endl;
        cout<<surname<<endl;
        cout<<age<<endl;
        cout<<ID<<endl;
        cout<<marks_sum<<endl;
        cout<<belonging_class<<endl;
    }

    friend std::ostream& operator << (std::ostream& os, const STUDENT& value )
    {
        os << value.name<<" "<<value.surname<<" "<<value.age<<" "<<value.ID<<" "<<value.marks_sum<<" "<<value.belonging_class<<std::endl;
        return os;
    }
};

STUDENT student1;

int writeInFile(STUDENT studentx)
{
    ofstream os("Students.txt", ofstream::app);
    os << studentx;
    os.close();
}


int main()
{
    int opt1, opt2;
    char option;

    do
    {
        cout<<"1 -  Input data into file"<<endl<<"2 - Close program"<<endl;
        cin>>opt1;
        switch(opt1)
        {
        case 1:
            do
            {
                cout<<endl;
                cout<<"Choose one of variants"<<endl<<"1.Students"<<endl<<"2.Get back to main menu"<<endl;
                cin>>opt2;
                switch(opt2)
                {
                case 1:
                    do
                    {
                        cout<<"Do you wish to introduce a new student(Y/N)?";
                        cin>>option;
                        if(option!='N')
                        {
                            student1.inputInfo();
                            writeInFile(student1);
                        }
                    }
                    while (option!='N');
                    break;
                }

            }
            while(opt2!=2);
            break;
        }
    }
    while(opt1!=2);

}

1 Ответ

1 голос
/ 21 октября 2019
#include <sstream>

using namespace std;

bool isUniqueID(ifstream& file, int id)
{

    string id_string = to_string(id);
    string currently_read_line;
    // The position of the searched key. So, in this case,
    // only the 3rd value will be tested (starting from 0).
    // John Doe 23 456
    //   |   |   |   |
    //   0   1   2   3 (the id)
    int offset = 3;

    while (getline(file, currently_read_line))
    {
        istringstream ss(currently_read_line);
        string current_entry;
        int counter = 0;

        while (ss >> current_entry) {

            if (current_entry == id_string && counter == offset) {
                cout << "The Id already exists." << endl;
                return false;
            }
            counter++;

        }
    }

    // No match found
    cout << "The ID does not exist yet." << endl;
    return true;

}

Обратите внимание:

  • Просто передайте открытый файл функции. Файл открывается один раз, вместо того, чтобы открывать его каждый раз, когда вы хотите проверить идентификатор.
  • Это требует компиляции в -std = c ++ 11 (для преобразования to_string)

[Обновить]

Переменная смещения сообщает функции, какое значение проверить. Более последовательный способ сделать это - отформатировать данные так, чтобы они имели ключ / значение для каждой записи студента. Это работает как это все же.

...