РЕШЕНО ВНИЗ.
У меня есть программа на 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);
}