scypx
scypx

Reputation: 87

Deleting record from file

So I have a record of students for instance:

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

Task is to delete record by searching name. Problem is my code deletes the whole data starting from name search. Like, if I have to delete record of name2, the data should be:

name,age,contact
name3,age3,contact3

But my code does:

name,age,contact

thus deleting the whole data present downwards of it if it finds the name. Been stuck at this problem.. Here is the code:

#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;
            }
}

Upvotes: 0

Views: 135

Answers (3)

Michael
Michael

Reputation: 950

Seems as you have couple of issues:

  1. First call to cin.ignore results in discarding the first input character, which you probably don't want.
  2. Why do you need both i and j? seems as you need only one of them, and it should equal 0 at the beginning of each loop iteration.
  3. else if (flag == true). The else if is checked only if the previous condition was not met, but if it was not met, then flag is necessarily true. Change it to if (flag == true), or simply if (flag)
  4. Don't using namespace std

Good luck!

Edit: I applied the fixes, and added a check after every Input/Output (IO) operation. the code as follows:

#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;
}

Upvotes: 1

Adrian Mole
Adrian Mole

Reputation: 51915

There are several problems in your code.

The first (and, perhaps, most obvious) is that you are not resetting i and j to zero at the start of each of the while loops - which means that your if (names[i] == search[j]) will be comparing two characters that are (possibly) beyond the end of the given names input (and also the search string) on all records after which a match has been found. Solution: set i and j to zero at the beginning of each while loop, in the same way as you reset flag. (Further, it is unclear to me why you need two different variables, here: i and j will always have the same value, so just use one and discard the other).

A second problem is the line else if(flag == true). This means that, once the first character of a name matches the first character of the search (i.e. the associated if (names[i] == search[j]) block has been entered), then you will not be writing that record to the output file. Solution: remove the else word - you are testing if a complete match has been found by setting flag to false, so you need to test that even if the preceding if block has been entered, and not found a complete match.

As a further 'improvement', you could actually declare the i, (j, ) age and flag variables inside the while loop, setting their initial values in those declarations.

Upvotes: 1

Jesper Juhl
Jesper Juhl

Reputation: 31488

Simplest approach (IMHO):

Read the entire file into memory. Edit what needs to be edited (in memory). Then overwrite the old file with the new content (or, write to new file, delete old file and then atomically rename new file to old file name).

You cannot insert (or delete) data in the middle of a file. You can only either overwrite existing data with same length or rewrite the file.

Upvotes: 0

Related Questions