Удаление записи из файла - PullRequest
0 голосов
/ 08 апреля 2020

Итак, у меня есть запись о студентах, например:

name,age,contact
name2,age2,contact2
name3,age3,contact3

Задача - удалить запись, выполнив поиск по имени. Проблема в том, что мой код удаляет все данные, начиная с поиска по имени. Например, если мне нужно удалить запись name2, данные должны быть:

name,age,contact
name3,age3,contact3

Но мой код делает:

name,age,contact

, таким образом, удаляя все имеющиеся данные вниз, если они находит имя. Застрял в этой проблеме .. Вот код:

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
            char names[30], search[30], contact[30];
            int i = 0, j = 0, age=0;
            bool flag;
            cout << "Enter name from records : ";
            cin.ignore();
            cin.getline(search, 19);
            ifstream fin;
            fin.open("studentinfo.txt");
            ofstream fout;
            fout.open("output.txt");
            if (fin.is_open())
            {
                while (!fin.eof())
                {
                    flag = true;
                    fin.getline(names, 19, ',');
                    fin >> age;
                    fin.ignore();
                    fin >> contact;
                    fin.ignore();
                    if (names[i] == search[j])
                    {
                        while (names[i] == search[j] && names[i] != ',' && search[j] != '\0')
                        {
                            i++;
                            j++;
                        }

                        if (search[j] == '\0')
                        {
                            flag = false;
                        }
                    }
                    else if(flag == true)
                        fout << names << ',' << age << ',' << contact << endl;
                }
                fin.close();
                fout.close();
            }

            else
            {
                cout << "file not found \n" << endl;
                return 0;
            }
}

Ответы [ 3 ]

1 голос
/ 08 апреля 2020

В вашем коде есть несколько проблем.

Первая (и, пожалуй, самая очевидная) заключается в том, что вы не сбрасываете i и j в ноль в начале каждого из while loop - это означает, что ваш if (names[i] == search[j]) будет сравнивать два символа, которые (возможно) выходят за пределы указанного ввода names (а также строки search) во всех записях, после которых найдено совпадение , Решение: установите i и j в ноль в начале каждый while l oop, так же, как вы сбросили flag. (Кроме того, мне непонятно, зачем вам нужны две разные переменные, здесь: i и j всегда будут иметь одинаковое значение, поэтому просто используйте одну и отбросьте другую).

Вторая проблема это линия else if(flag == true). Это означает, что, как только первый символ имени совпадает с первым символом поиска (т. Е. Был введен связанный блок if (names[i] == search[j])), вы не будете записывать эту запись в выходной файл. Решение: удалите слово else - вы проверяете, найдено ли совпадение complete , установив для flag значение false, поэтому вам нужно проверить это , даже если предыдущий блок if был введен и не нашел полного соответствия .

В качестве дополнительного «улучшения» вы могли бы объявить i, (j,) age и flag переменные внутри while l oop, устанавливающие их начальные значения в этих объявлениях.

1 голос
/ 08 апреля 2020

Похоже, у вас есть пара проблем:

  1. Первый вызов cin.ignore приводит к отбрасыванию первого входного символа, который вам, вероятно, не нужен.
  2. Почему вам нужны оба i и j? Кажется, вам нужен только один из них, и он должен равняться 0 в начале каждой итерации l oop.
  3. else if (flag == true). else if проверяется только в том случае, если предыдущее условие не было выполнено, но если оно не было выполнено, то flag обязательно равно true. Измените его на if (flag == true) или просто if (flag)
  4. Не using namespace std

Удачи!

Редактировать: я применил исправления, и добавлена ​​проверка после каждой операции ввода / вывода (IO). код следующим образом:

#include<iostream>
#include<fstream>

int main()
{
    char names[30], search[30], contact[30];
    int i = 0, age = 0;
    bool flag;

    std::cout << "Enter name from records : ";
    std::cin.getline(search, 19);

    std::ofstream fout("output.txt");
    if (!fout) {
        std::cout << "Failed opening output file" << std::endl;
        return 1;
    }

    std::ifstream fin("studentinfo.txt");
    if (!fin) {
        std::cout << "file not found" << std::endl;
        return 1;
    }

    while (!fin.eof())
    {
        i = 0;
        flag = true;
        fin.getline(names, 19, ',');
        fin >> age;
        fin.ignore();
        fin >> contact;
        fin.ignore();
        if (!fin) {
            std::cout << "Failed reading from file" << std::endl;
            return 2;
        }
        if (names[i] == search[i])
        {
            while (names[i] == search[i] && names[i] != ',' && search[i] != '\0')
            {
                i++;
            }

            if (search[i] == '\0')
            {
                flag = false;
            }
        }
        if (flag) {
            fout << names << ',' << age << ',' << contact << std::endl;
        }
    }

    fin.close();
    fout.close();

    return 0;
}
0 голосов
/ 08 апреля 2020

Простейший подход (ИМХО):

Считать весь файл в память. Отредактируйте то, что нужно отредактировать ( в памяти ). Затем перезаписать старый файл новым содержимым (или записать в новый файл, удалить старый файл и затем атомарно переименовать новый файл в старое имя файла).

Вы не можете вставить (или удалить) данные в середине файл. Вы можете либо перезаписать существующие данные одинаковой длины, либо перезаписать файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...