2014-11-25 14 views
-1

我正在使用數組和結構來完成我的可憐的編程技巧。我無法弄清楚如何將數組移到右側。在editContact函數中,我試圖在名稱更改後按姓氏對聯繫人進行排序。計劃是將陣列右移,並將編輯後的聯繫人放入適當的字母順序位置。不能右移使用地址簿程序中的數組和結構C++

我需要把 「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 *'賦值爲'聯繫人[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]; 
+0

請閱讀下面的內容:http:// stackoverflow。com/help/mcve,遵循這些建議將幫助你解決問題。 – shuttle87 2014-11-25 03:33:59

+0

@ shuttle87謝謝。 – dumberthanyou 2014-11-25 03:41:35

+0

感謝您的閱讀,我收回了我的近距離投票。好,所以我在這裏看到的是一個可能的[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem),你是什麼意思「可以將數組向右移動「,也許更重要的是*爲什麼*你想這樣做?你想在這裏解決什麼問題? – shuttle87 2014-11-25 03:53:15

回答

0

技術上,而不是這樣的:

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

Raw數組有一些問題,包括如何安全find the size

使用C++ 11及更高版本,而不是上述C表達式考慮使用std::end(a) - std::begin(a),表示爲函數模板(例如size)。


此外,可能會或將會發現訴諸通過對於每個新的項目移,給人爲O(n 2 )時間。物品越多越慢,物品越多。不成比例地如此。

這也是使用標準庫容器的一個很好的理由。

他們採用更有效的策略來保存事物的排序。

+0

'sizeof(entries)'給出了以字節爲單位的大小,而不是元素。除非'sizeof(Contact)'恰好爲1,否則你的代碼有一個緩衝區溢出。即使'n'被正確計算,'entry [i + 1]'仍然在最後一次迭代中超出界限。 – 2014-11-25 04:15:30

+0

@IgorTandetnik:謝謝。我在這裏寫了[關於這個問題的常見問題](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c/7439261#7439261),所以我可以證明它。修正了錯別字。 – 2014-11-25 04:17:07

+0

'shiftUp(0)'仍然有訪問限制。 – 2014-11-25 04:21:37