Невозможно сместить вправо, используя массивы и структуры в программе адресной книги. Переполнение стека

Я работаю над проектом, использующим массивы и структуры, чтобы улучшить мои слабые навыки программирования. Я не могу понять, как сдвинуть массив вправо. В функции editContact я пытаюсь отсортировать контакты по фамилии после изменения имени. План состоит в том, чтобы сместить массив вправо и поместить отредактированный контакт в соответствующее место в алфавитном порядке.

Нужно ли ставить
«int numContacts = 0;
Контактные записи [500]; «в структуру?

Вот код, с которым я борюсь конкретно:

void shiftUp(int startIndex) {

entries = new int[entries.Length];

for (int i = startIndex; i < entries.Length - 1; i++)
{
entries[i] = entries[i + 1];
}

entries[entries.Length - 1] = entries[0];

}

Это сообщение об ошибке, которое я получаю от компилятора:

addressbook.cpp: 311: ошибка: запрос на член «Длина» в «записях», который имеет неклассный тип «Контакт [500]»
addressbook.cpp: 311: ошибка: несовместимые типы в присваивании ‘int *’ для ‘Contact [500]’
addressbook.cpp: 313: ошибка: запрос на член «Длина» в «записях», который имеет неклассный тип «Контакт [500]»
addressbook.cpp: 318: ошибка: запрос на член «Длина» в «записях», который имеет неклассный тип «Контакт [500]»

Это основная часть программы:

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

/*structures*/
struct Contact {
string firstName;
string lastName;
string middleInitial;
string phoneNumber;
string streetAddress;
string city;
string state;
string zipCode;
};

int numContacts=0;
Contact entries[500];

/*prototypes*/
int mainMenu();
int searchResults(string searchTerm);
void searchContacts();
void contactDetail(int contactIndex);
void editContact(int contactIndex);
bool deleteContact(int contactIndex);
void listContacts();
void addContact();
void shiftUp(int startIndex);
void shiftDown(int startIndex);
void saveData();
void loadData();
int findLocation(string lastName);
void saveContact(ofstream dataFile, Contact& newContact);
void loadContact(ifstream dataFile, Contact& newContact);

/*consts*/
const int SEARCH_CMD = 1;
const int LIST_CMD = 2;
const int ADD_CMD = 3;
const int EXIT_CMD = 4;

int main(){
loadData();
int selection;
do {
selection = mainMenu();
switch(selection) {
case SEARCH_CMD:
searchContacts();
break;
case LIST_CMD:
listContacts();
break;
case ADD_CMD:
addContact();
break;
}
} while (selection !=EXIT_CMD);
saveData();
}

int mainMenu(){
/*show the menu*/

cout << "**** Welcome to AddressBook ****" << endl << "1. Search for Contacts" << endl << "2. List Contacts" << endl << "3. Add New Contact" << endl << "4. Exit" << endl << "Enter Selection:";
/*input the selection*/
int selection;
while(1) {
cin >> selection;
/*validate the selection and reprompt if neccessary*/
if ((selection >4) || (selection < 1)) {
cout << "This is not a valid menu option. Please try again.";
break;
}
if ((selection <=4) && (selection >=1)) {
break;
}

}
/* return a valid selection */
return(selection);
}
void searchContacts() {
/*output "Enter search term: " */
cout << "Enter search term: ";
/*input the string searchTerm */
string searchTerm;
cin >> searchTerm;
/* call searchResults(searchTerm) */
searchResults(searchTerm);
}
int searchResults(string searchTerm){
/* output "Search Results:"*/
int noMatch =0;
cout << "Search Results: " << endl;
/*loop through every contact*/
int contactsIndex[500];
for (int i=0; i<=numContacts; i++) {
if (entries[i].lastName == searchTerm) {
noMatch++;
cout << noMatch << ". " << entries[i].firstName << " " << entries[i].lastName << " " << entries[i].phoneNumber << endl;
contactsIndex[noMatch] = i;
}
}
if (noMatch == 0) {
cout << "No match found\n";
return(1);
}
int selectContact;
cout << "Select a contact (or M for Main Menu): ";
cin >> selectContact;
if ((selectContact > 0) && (selectContact <= noMatch)) {
contactDetail(contactsIndex[selectContact]);
}
if ((selectContact=='m') || (selectContact=='M')) {

}

/*  compare each field (using substr) to searchTerm*/
/*  if the searchTerm is in any field, output the contact*/
/*  save the index of the contact to contactsIndex array*/
/* output "Select a Contact (or M for Main Menu): "*/
/*input selection*/
/*if selection is a contact number, call contactDetail(contactsIndex[selection-1]);*/
}
void contactDetail(int contactsIndex){

/*show the indicated contact - addressBook.entries[contactIndex]*/
cout << entries[contactsIndex].firstName << " " << entries[contactsIndex].middleInitial << ". " << entries[contactsIndex].lastName << endl;
cout << entries[contactsIndex].streetAddress << endl << entries[contactsIndex].city << ", " << entries[contactsIndex].state << ", " << entries[contactsIndex].zipCode << endl;
cout << "Phone: " << entries[contactsIndex].phoneNumber << endl;
/* output "Select E for Edit, D to delete or M for Main Menu: "*/
cout << "Select E for Edit, D to delete, or M for Main Menu:" ;
/* read selection*/
char menuSelection;
cin >> menuSelection;
/*if selection is E*/
if (menuSelection == 'E') {
editContact(contactsIndex);
}
/*  editContact(contactIndex)*/
/*if selection is D*/
if (menuSelection == 'D') {
bool retValue;
retValue = deleteContact(contactsIndex);
}
/*  retValue = deleteContact(contactIndex)*/
/*else m, break*/
if (menuSelection == 'M') {

}
/* loop while retValue is false*/
}
void editContact(int contactsIndex){
/*output "**Press Enter to leave field unchanged. Enter a new value to change it.**"*/
cout << "Press Enter to leave field unchanged. Enter a new value to change it." << endl;
/*use addressBook.entries[contactIndex]*/
string editEntry;
cout << "First Name: ";
cin >> editEntry;
entries[contactsIndex].firstName = editEntry;

cout << "Last Name: ";
cin >> editEntry;
entries[contactsIndex].lastName = editEntry;

cout << "Middle Initial: ";
cin >> editEntry;
entries[contactsIndex].middleInitial = editEntry;

cout << "Phone Number: ";
cin >> editEntry;
entries[contactsIndex].phoneNumber = editEntry;

cout << "Street Address: ";
cin >> editEntry;
entries[contactsIndex].streetAddress = editEntry;

cout << "City: ";
cin >> editEntry;
entries[contactsIndex].city = editEntry;

cout << "State: ";
cin >> editEntry;
entries[contactsIndex].state = editEntry;

cout << "Zip Code: ";
cin >> editEntry;
entries[contactsIndex].zipCode = editEntry;

/*     prompt for each field */
/*     input fields*/
/*     if input is not empty*/
/*         set corresponding field with input*/
/* shiftUp(contactIndex)*/
shiftUp(contactsIndex);
int newIndex;
newIndex = findLocation (entries[contactsIndex].lastName);
/* newIndex = findLocation(lastName)
if (newIndex != numContacts) {
shiftDown(newIndex);

}*/

/* if newIndex != numContacts*/
/*      shiftDown(newIndex)*/
/* add the new contact at [newindex]*/
/* output "Select E to Edit or M for  Main Menu: "*/
/* if selection is Edit*/
/*loop*/
}
bool deleteContact(int contactIndex){
/*output "Are you sure you want to delete this contact? (Y/N): "*/
/*read selection*/
/*validate selection*/
/* if yes*/
/*shiftUp(contactIndex)*/
/* output "Contact deleted! Press any key to return to main menu."*/
/*return true - means contact was deleted*/
/*else if No*/
/*return false*/
return(false);
}
void listContacts(){
/*output "Contact List: "*/
cout << "Contact List: " << endl;
/* for all contacts:*/
for (int i=0; i < numContacts; i++) {
cout << entries[i].firstName << " " << entries[i].middleInitial << ". " << entries[i].lastName << endl;
cout << entries[i].streetAddress << endl << entries[i].city << ", " << entries[i].state << ", " << entries[i].zipCode << endl;
cout << "Phone: " << entries[i].phoneNumber << endl << endl;

/*      output firstName, lastName, and phone (formatted)*/
/* output "Select a Contact (or M for Main Menu): "*/
/*input selection*/
/*validate selection*/
/*if selection is a contact number, call contactDetail(contactsIndex[selection-1]);*/
}
}

void addContact(){

cout << "Add A Contact! Please enter each value as prompted." << endl;
/*
string newEntry;
cout << "First Name: ";
cin >> newEntry;
entries[contactsIndex].firstName = newEntry;

cout << "Last Name: ";
cin >> newEntry;
entries[contactsIndex].lastName = newEntry;

cout << "Middle Initial: ";
cin >> newEntry;
entries[contactsIndex].middleInitial = newEntry;

cout << "Phone Number: ";
cin >> newEntry;
entries[contactsIndex].phoneNumber = newEntry;

cout << "Street Address: ";
cin >> newEntry;
entries[contactsIndex].streetAddress = newEntry;

cout << "City: ";
cin >> newEntry;
entries[contactsIndex].city = newEntry;

cout << "State: ";
cin >> newEntry;
entries[contactsIndex].state = newEntry;

cout << "Zip Code: ";
cin >> newEntry;
entries[contactsIndex].zipCode = newEntry;
*/
/*First Name:*/
/*Last Name:*/
/*Middle Initial:*/
/*Phone Number:*/
/*Street Address:*/
/*City: */
/*State:*/
/*Zip Code:*/

/* add the new contact to the addressBook*/
/* newIndex = findLocation(lastName)*/
/* if newIndex != numContacts*/
/*      shiftDown(newIndex)*/
/* add the new contact at [newindex]*/
/* addressBook.numContacts++*/
/*set contactIndex to index of added contact*/
/*Enter 'E' for Edit Again, 'D' to Delete, or 'M' for Main Menu: M*/
/*if selection is E*/
/*  editContact(contactIndex)*/
}

void shiftDown(int startIndex) {
/*shift the addressBook.entries up */
/*starting at startIndex+1 through the end of the array (loop should loop from bottom)*/
/*addressBook.numContacts++;*/
}

void shiftUp(int startIndex) {

entries = new int[entries.Length];

for (int i = startIndex; i < entries.Length - 1; i++)
{
entries[i] = entries[i + 1];
}

entries[entries.Length - 1] = entries[0];/*shift the addressBook.entries down */
/*starting at startIndex through the end of the array (loop should loop from top)*/
/*addressBook.numContacts--;*/
}

int findLocation(string lastName) {
/*go through the addressBook and find the first lastName that is greater than the lastName passed to the function*/
int nameOrder;
for (int i=0; lastName < entries[i].lastName; i++) {
nameOrder++;
}
/* if you reach the end of the array, return the number of the next available slot*/
return(nameOrder);
}

void loadData(){
string newContact;
ifstream dataFile;
dataFile.open("addressBook.dat");
/*open addressBook.dat for input. call stream dataFile*/
/*for loop until end of file using i as loop counter*/
if (dataFile.is_open()) {
for (int i=0;!dataFile.eof();i++) {
getline (dataFile,newContact);
entries[i].firstName = newContact;
cout << entries[i].firstName << endl;

getline (dataFile,newContact);
entries[i].lastName = newContact;
cout << entries[i].lastName << endl;

getline (dataFile,newContact);
entries[i].middleInitial = newContact;

getline (dataFile,newContact);
entries[i].phoneNumber = newContact;

getline (dataFile,newContact);
entries[i].streetAddress = newContact;

getline (dataFile,newContact);
entries[i].city = newContact;

getline (dataFile,newContact);
entries[i].state = newContact;

getline (dataFile,newContact);
entries[i].zipCode = newContact;
numContacts++;
}
}
else cout << "Unable to open file";
/*loadContact(dataFile, addressBook.entries[i]);*/
/*close addressBook.dat*/
dataFile.close();
}

Спасибо за вашу помощь, это решение, которое я в конечном итоге использовал

void shiftUp(int startIndex) {
/*shift the addressBook.entries up to delete entries*/
/*starting at startIndex+1 through the end of the array (loop should loop from bottom)*/
for (int i = startIndex; i <= numContacts; ++i ){
entries[i] = entries[i+1];

-1

Решение

Технически, вместо этого:

void shiftUp(int startIndex) {

entries = new int[entries.Length];

for (int i = startIndex; i < entries.Length - 1; i++)
{
entries[i] = entries[i + 1];
}

entries[entries.Length - 1] = entries[0];

}

делать:

void shiftUp( int startIndex )
{
int const n = sizeof( entries )/sizeof( *entries );
for( int i = n - 1; i > startIndex; --i )
{
entries[i] = entries[i - 1];
}
}

Изучите различия, чтобы узнать некоторые новые вещи C ++.


Вместо необработанных массивов рассмотрите возможность использования контейнеров стандартной библиотеки C ++, таких как vector а также map,

У сырых массивов есть некоторые проблемы, в том числе как безопасно найти размер.

В C ++ 11 и более поздних версиях вместо приведенного выше выражения C рассмотрите возможность использования std::end(a) - std::begin(a)выражается в виде шаблона функции (например, называется size).


Кроме того, вы можете или обнаружите, что при переходе на новую позицию2Время Вещи становятся все медленнее и медленнее, чем больше предметов у вас есть. Непропорционально так.

Это также хорошая причина для использования стандартных библиотечных контейнеров.

Они используют гораздо более эффективные стратегии для сортировки вещей.

0

Другие решения


По вопросам рекламы [email protected]