无法使用地址簿程序 c++ 中的数组和结构向右移动

Cannot shift right using arrays and structures in address book program c++

本文关键字:数组 结构 移动 右移 地址簿 c++ 程序      更新时间:2023-10-16

我正在做一个使用数组和结构的项目,以进一步提高我糟糕的编程技能z。我不知道如何将数组向右移动。在函数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];
}

这是我从编译器收到的错误消息:

地址簿.cpp:311:错误:请求"条目"中的成员"长度",该成员属于非类类型"联系人 [500]"地址簿.cpp:311:错误:将"int*"分配给"联系人 [500]"时的类型不兼容地址簿.cpp:313:错误:请求"条目"中的成员"长度",该成员的非类类型为"联系人 [500]"地址簿.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 foundn";
            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];  

从技术上讲,而不是这个:

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++标准库容器(如 vectormap)代替原始数组。

原始数组存在一些问题,包括如何安全地找到大小。

对于 C++11 及更高版本,请考虑使用 std::end(a) - std::begin(a) 代替上述 C 表达式,表示为函数模板(例如称为 size )。


此外,您可能会或将发现,通过为每个新项目移动来重新排序,会给 O(n2) 时间。事情只会随着您拥有的物品越多而变慢。不成比例地如此。

这也是使用标准库容器的一个很好的理由。

他们采用更有效的策略来保持事物的分类。