C Функция для добавления дополнительной структуры в массив не может правильно добавить более одной структуры - PullRequest
0 голосов
/ 02 апреля 2019

РЕШЕНО ВНИЗ.

У меня есть программа на C, предназначенная для сохранения, редактирования и удаления контактов и сохранения их в двоичном файле.Структура для контакта определяется следующим образом:

    struct Contact {
        unsigned long phone_number;
        long first_name_posn;
        long last_name_posn;
        long company_name_posn;
        long email_posn;
        long next;
    }

Каждое значение, кроме phone_number, содержит местоположение информации в файле, и информация записывается сразу после.Теперь, когда программа работает, я читаю все контакты в динамический массив.Функция ниже предназначена для добавления дополнительного контакта в массив и его сохранения.Однако, когда я начинаю с нуля контактов и добавляю один, это нормально.Но когда я пытаюсь добавить второй контакт, он, кажется, перекрывает первый и заставляет программу прочитать неверную информацию.

Я считаю, что это как-то связано с моим заявлением realloc, хотя я понятия не имею, чтоможет быть не так.Я попытался создать второй массив и переместить его в этот массив, но это также не удалось.

int addContact(Contact *contacts, FILE *fptr, int size)
{
    char *fName, *lName, *company, *email;
    unsigned long phone;
    long next;
    char input[MAX_STRING_SIZE];

    /* Gets the first name */
    printf("First Name: ");
    fgets(input, MAX_STRING_SIZE, stdin);
    fName = toPointer(input);

    /*Gets the last name or company name */
    do
    {
        printf("Last Name: ");
        fgets(input, MAX_STRING_SIZE, stdin);
        lName = toPointer(input);

        printf("Company Name: ");
        fgets(input, MAX_STRING_SIZE, stdin);
        company = toPointer(input);

    } while ((lName[0] == '\0' || lName[0] == '\n') && (company[0] == '\0' || company[0] == '\n'));

    /* Gets the phone number */
    do
    {
        printf("Phone Number (enter only numbers): ");
        fgets(input, MAX_STRING_SIZE, stdin);

        if (input[0] != '\0' && input[0] != '\n')
        {
            sscanf(input, "%ld", &phone);
        }
    } while ((phone < 1000000 || phone > 9999999) && (phone < 1000000000 || phone > 9999999999));

    do
    {
        printf("Email: ");
        fgets(input, MAX_STRING_SIZE, stdin);
        email = toPointer(input);

    } while (!isValidEmail(email));

    printf("Action: ");
    fgets(input, MAX_STRING_SIZE, stdin);
    lowerCase(input);

    if (input[0] == 's' && input[1] == '\0')
    {
        next = getNext(fptr);
        printf("Size: %d\n", size);
        contacts = realloc(contacts, sizeof(Contact) * (size+1));
        fseek(fptr, 0, SEEK_END);

        /* Calculates the position for the contact */
        contacts[size].phone_number = phone;
        contacts[size].first_name_posn = next + sizeof(Contact);
        contacts[size].last_name_posn = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1));
        contacts[size].company_name_posn = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1)) + (sizeof(char) * (strlen(lName)+1));
        contacts[size].email_posn = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1)) + (sizeof(char) * (strlen(lName)+1)) + (sizeof(char) * (strlen(company)+1));
        contacts[size].next = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1)) + (sizeof(char) * (strlen(lName)+1)) + (sizeof(char) * (strlen(company)+1)) + (sizeof(char) * (strlen(email)+1));

        fwrite(&contacts[size], sizeof(Contact), 1, fptr);
        fwrite(fName, sizeof(char) * (strlen(fName)+1), 1, fptr);
        fwrite(lName, sizeof(char) * (strlen(lName)+1), 1, fptr);
        fwrite(company, sizeof(char) * (strlen(company)+1), 1, fptr);
        fwrite(email, sizeof(char) * (strlen(email)+1), 1, fptr);

        size++;
    }

    free(fName);
    free(lName);
    free(company);
    free(email);

    return size;
}

Если я введу эти два контакта:

Имя: Джон

Фамилия: Смит

Компания: Рик

Телефон: 1234567899

Электронная почта: jsmith@hotmail.com

Имя: Боб

Фамилия: Evergreen

Компания:

Телефон: 5194567895

Электронная почта: bobgreen@gmail.com

Это избавит от имени Джона,и измените номер телефона на 6445449192 другой, оставаясь таким же для этого контакта.Для второго контакта вся информация - «ом», номер телефона - 64.

Для решения я изменил параметры на:

int addContact(Contact **contacts, FILE *fptr, int size);

Затем в операторе if Iвнесены коррективы в письменной форме.Добавлен временный контакт для добавления информации, а другой - для копирования старого массива в новый с большим количеством места.Затем я копирую данные из одного контакта в другой, чтобы обновить массив.Вот где изменения:

if (input[0] == 's' && input[1] == '\0')
    {
        next = getNext(fptr);
        printf("Size: %d\n", size);
        Contact *temp = malloc(sizeof(Contact));
        fseek(fptr, 0, SEEK_END);

        /* Calculates the position for the contact */
        temp->phone_number = phone;
        temp->first_name_posn = next + sizeof(Contact);
        temp->last_name_posn = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1));
        temp->company_name_posn = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1)) + (sizeof(char) * (strlen(lName)+1));
        temp->email_posn = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1)) + (sizeof(char) * (strlen(lName)+1)) + (sizeof(char) * (strlen(company)+1));
        temp->next = next + sizeof(Contact) + (sizeof(char) * (strlen(fName)+1)) + (sizeof(char) * (strlen(lName)+1)) + (sizeof(char) * (strlen(company)+1)) + (sizeof(char) * (strlen(email)+1));

        printf("Adding Space\n");
        Contact *newContacts = realloc(*contacts, sizeof(Contact) * (size+1));
        *contacts = newContacts;
        (*contacts)[size].phone_number = temp->phone_number;
        (*contacts)[size].first_name_posn = temp->first_name_posn;
        (*contacts)[size].last_name_posn = temp->last_name_posn;
        (*contacts)[size].company_name_posn = temp->company_name_posn;
        (*contacts)[size].email_posn = temp->email_posn;
        (*contacts)[size].next = temp->next;

        printf("Writing Contacts\n");
        fwrite(temp, sizeof(Contact), 1, fptr);
        fwrite(fName, sizeof(char) * (strlen(fName)+1), 1, fptr);
        fwrite(lName, sizeof(char) * (strlen(lName)+1), 1, fptr);
        fwrite(company, sizeof(char) * (strlen(company)+1), 1, fptr);
        fwrite(email, sizeof(char) * (strlen(email)+1), 1, fptr);
        printf("Dont Writing\n");

        size++;
        free(temp);
        free(newContacts);
    }
...