删除功能的问题

时间:2015-07-23 08:33:48

标签: c

我写了一个电话簿程序。但是,我遇到了删除功能的问题。例如,当我编译下面的代码并按照这样的方式时;

我打开一个文件并通过输入1(通过使用第一个函数)将某人添加到列表中,之后我输入5以从列表中删除此人。正如预期的那样,它正确地删除了第一条记录。

从现在开始,我通过输入4(通过使用添加功能)添加另一个人列表,并再次删除我输入5的最后一个人并通知删除“1”(通过使用删除功能)。

之后它在屏幕上显示一条警告,如“记录已被清除”。但是,我看到最后一条记录仍然停留,当我查看文件记录位置的位置并使用第二功能时

为什么在第一次删除时,第二次没有?

#include <stdlib.h>      // "stdlib" library contains of exit() function
#include <malloc.h>     // "malloc" library contains of malloc() function
#include <Windows.h>   // "Windows" library contains of Sleep() function which waits the system as you want
#include <io.h>       // "io" library contains of filelength() function
#include <string.h>  // "string" library contains of strlen() function
#include <stdio.h>  // "stdio" library contains of other functions which hasn't been mentioned

struct personKnowledge   // Structe and it's elements are being defined
{
    char name[32];
    char surname[32];
    char number[32];
};

FILE *ptrFILE, *ptrFILE1;   // Variables are being defined
long int recordLength, totalRecordLength, location;
int choice, number, totalRecordNumber, i;
static int counter = 0;

int menu();   // Functions are being defined
void newRecord();
void display();
void update();
void add();
void deletE();

int main()   // Program is being initialiezed 
{
    menu();
    return 0;
}

int menu()   // Options are being presented to user 
{
    do
    {
        printf("\n\t\t --- Phone Book Program ---");
        printf("\n\n\t\t 1) Open file and record someone");
        printf("\n\n\t\t 2) Display person knowledge");
        printf("\n\n\t\t 3) Update person knowledge");
        printf("\n\n\t\t 4) Add person to list");
        printf("\n\n\t\t 5) Delete someone");
        printf("\n\n\t\t 6) Exit");
        printf("\n\n\nEnter your choice: ");
        choice = 0;
        scanf("%d", &choice);
        fflush(stdin);
        switch (choice)
        {
        case 1:
        {
            newRecord();
            break;
        }
        case 2:
        {
            display();
            break;
        }
        case 3:
        {
            update();
            break;
        }
        case 4:
        {
            add();
            break;
        }
        case 5:
        {
            deletE();
            break;
        }
        case 6:
        {
            printf("\nWorking has been completed.\n");
            return 0;
        }
        default:
        {
            printf("\nWrong entry! The program has been terminated.\n");
            break;
        }
        }
    } while (choice >= 1 && choice <= 6);
}

void newRecord()   // This function opens a file and records one person in file
{
    if (counter > 0)
    {
        system("cls");   // Screen is being cleaned
        Sleep(350);     // Sleep functions waits user for a while
        printf("\nYou have already entered '1' and opened a file. To add a person please enter '4'\n");
        return;
    }
    else
    {
        if ((ptrFILE = fopen("Phone Book.dat", "wb")) == NULL)   // wb is binary writing mode
        {
            printf("The file couldn't open\n");
            exit(EXIT_SUCCESS);
        }
        system("cls");
        Sleep(350);
        struct personKnowledge *p;   // p = (Person)
        p = (struct personKnowledge *)malloc(sizeof(struct personKnowledge));   // Memory is being allocated
        fflush(stdin);   // Cache memory is being cleaned
        recordLength = sizeof(*p);
        printf("\n\Express person name: ");   // User is entering the person's knowledge and they are being saved in file
        fgets(p->name, sizeof(p->name), stdin);
        size_t wordLength = strlen(p->name);  // "size_t is unsigned integer type"
        if (wordLength > 0 && p->name[wordLength - 1] == '\n')   // This if idiom has been used for sentence seperation
        {
            p->name[--wordLength] = '\0';
        }
        printf("Express %s's surname: ", p->name);
        fgets(p->surname, sizeof(p->surname), stdin);
        printf("Express %s's number: ", p->name);
        fgets(p->number, sizeof(p->number), stdin);
        fwrite(&(*p), recordLength, 1, ptrFILE);   // Knowledge which has been got from user is being saved in file processionally
        printf("\nPlease wait, information is saving to file..\n");
        Sleep(750);
        printf("*-* Saving operation has been completed succesfully. *-*\n");
        free(p);   // Allocated part of memory is being released
    }
    fclose(ptrFILE);   // File is being closed
    counter++;
}

void display()   // If there is person knowledge which is searched in file, this function reads it and prints on the screen
{
    if ((ptrFILE = fopen("Phone Book.dat", "rb")) == NULL)   // rb is binary reading mode
    {
        printf("The file couldn't open\n");
        exit(EXIT_SUCCESS);
    }
    system("cls");
    Sleep(350);
    struct personKnowledge *s;   // s = (Searching)
    s = (struct personKnowledge *)malloc(sizeof(struct personKnowledge));
    recordLength = sizeof(*s);   // Necessary location calculations are being done and person's knowledge is being displayed
    totalRecordLength = filelength(fileno(ptrFILE));   // The equalities explains what the purpose is from 137th line to 145th line 
    totalRecordNumber = totalRecordLength / recordLength;
    printf("\n\nExpress person record number which you search: ");
    number = -791673918435;
    scanf("%d", &number);
    fflush(stdin);
    printf("\n*-* Person knowledge which you search *-*\n");
    Sleep(750);
    location = (number - 1)*(recordLength);
    fseek(ptrFILE, location, SEEK_SET);   // The cursor locates place which is searched with fseek() function
    if (fread(&(*s), recordLength, 1, ptrFILE) != 0 && number > 0)  // If there is knowledge in that location and numbeer is greater than 0
    {
        printf("Name: %s\n", s->name);
        printf("Surname: %s", s->surname);
        printf("Number: %s\n", s->number);
    }
    else
    {
        printf("There is no record like this.\n");
        return;
    }
    free(s);
    fclose(ptrFILE);
}

// In this function, the code line explanations are same as previous ones
void update()   // This function updates only one person knowledge from his/her name to phone number that gets from user again
{
    if ((ptrFILE = fopen("Phone Book.dat", "rb+")) == NULL)   // rb+ is both reading and writing mode
    {
        printf("The file couldn't open\n");
        exit(EXIT_SUCCESS);
    }
    system("cls");
    Sleep(350);
    struct personKnowledge *d;   // d = (Deleting)
    d = (struct personKnowledge *)malloc(sizeof(struct personKnowledge));
    recordLength = sizeof(*d);
    totalRecordLength = filelength(fileno(ptrFILE));
    totalRecordNumber = totalRecordLength / recordLength;
    if (totalRecordNumber == 0)
    {
        printf("\nThere is no any record to update.\n");
        return;
    }
    printf("\nEnter the person record number which you update: ");
    scanf("%d", &number);
    fflush(stdin);
    location = (number - 1)*(recordLength);
    fseek(ptrFILE, location, SEEK_SET);
    if (fread(&(*d), recordLength, 1, ptrFILE) == 0 || number <= 0)
    {
        Sleep(350);
        printf("There is no record like this.\n");
        return;
    }
    else
    {
        fseek(ptrFILE, location, SEEK_SET);
        printf("\n\Express new person name: ");
        fgets(d->name, sizeof(d->name), stdin);
        size_t wordLength = strlen(d->name);
        if (wordLength > 0 && d->name[wordLength - 1] == '\n')
        {
            d->name[--wordLength] = '\0';
        }
        printf("Express %s's surname: ", d->name);
        fgets(d->surname, sizeof(d->surname), stdin);
        printf("Express %s's number: ", d->name);
        fgets(d->number, sizeof(d->number), stdin);
        fwrite(&(*d), recordLength, 1, ptrFILE);
        printf("\nPlease wait, information is saving to file..\n");
        Sleep(750);
        printf("*-* Updating operation has been completed succesfully. *-*\n");
    }
    free(d);
    fclose(ptrFILE);
}

// In this function, the code line explanations are same as previous ones
void add()   // This functions records person in file as much as user wants
{
    if ((ptrFILE = fopen("Phone Book.dat", "ab")) == NULL)
    {
        printf("The file couldn't open\n");
        exit(EXIT_SUCCESS);
    }
    system("cls");
    Sleep(350);
    struct personKnowledge *a;   // a = (Adding)
    a = (struct personKnowledge *)malloc(sizeof(struct personKnowledge));
    fflush(stdin);
    recordLength = sizeof(*a);
    printf("\n\Express person name: ");
    fgets(a->name, sizeof(a->name), stdin);
    size_t wordLength = strlen(a->name);
    if (wordLength > 0 && a->name[wordLength - 1] == '\n')
    {
        a->name[--wordLength] = '\0';
    }
    printf("Express %s's surname: ", a->name);
    fgets(a->surname, sizeof(a->surname), stdin);
    printf("Express %s's number: ", a->name);
    fgets(a->number, sizeof(a->number), stdin);
    fwrite(&(*a), recordLength, 1, ptrFILE);
    printf("\nPlease wait, information is adding to file..\n");
    Sleep(750);
    printf("*-* Adding operation has been completed succesfully. *-*\n");
    free(a);
    fclose(ptrFILE);
}

void deletE()   // ??
{
    if ((ptrFILE = fopen("Phone Book.dat", "rb")) == NULL)
    {
        printf("The file couldn't open\n");
        exit(EXIT_SUCCESS);
    }
    if ((ptrFILE1 = fopen("Phone Book1.dat", "wb")) == NULL)
    {
        printf("The file couldn't open\n");
        exit(EXIT_SUCCESS);
    }
    system("cls");
    Sleep(350);
    struct personKnowledge *del;   // del = (Deleting)
    del = (struct personKnowledge *)malloc(sizeof(struct personKnowledge));
    fflush(stdin);
    recordLength = sizeof(*del);
    totalRecordLength = filelength(fileno(ptrFILE));
    totalRecordNumber = totalRecordLength / recordLength;
    printf("\nExpress person number which you want to delete: ");
    scanf("%d", &number);
    fflush(stdin);
    if (fread(&(*del), recordLength, 1, ptrFILE) == 0 || number <= 0)
    {
        Sleep(350);
        printf("There is no record like this.\n");
        return;
    }
    for (i = 1; i <= totalRecordNumber; i++)
    {
        if (i == number)
        {
            Sleep(350);
            printf("The record has been cleared.\n");
            continue;
        }
        else
        {
            fwrite(&(*del), recordLength, 1, ptrFILE1);
        }
    }
    fclose(ptrFILE);
    fclose(ptrFILE1);
    remove("Phone Book.dat");
    rename("Phone Book1.dat", "Phone Book.dat");
    free(del);
}

1 个答案:

答案 0 :(得分:0)

删除循环应如下所示(注意&(*ptr)与提供指针相同):

if (number <= 0)
{
    Sleep(350);
    printf("There is no record like this.\n");
    return;
}
found= 0;
while (fread(del, recordLength, 1, ptrFILE) != 0)
{
    if (atoi(del->number)==number)
    {
        Sleep(350);
        printf("The record has been cleared.\n");
        found= 1;
        continue;
    }
    else
    {
        fwrite(del, recordLength, 1, ptrFILE1);
    }
}
if (found==0) printf("There is no record like this.\n");