2015-11-08 98 views
-2

我想編寫一個程序,在命令行中的用戶將會把他們想進入名的數量,然後他們鍵入帶有名字和姓氏的名字,像下面:我該如何解決這個排序錯誤?

./Sort-names 5 
Andrew Hawking 
John Smith 
Stephen Hawking 
Alice Cooper 
Jean Smith 

,然後我會獲得這些投入,並與字母排序姓氏排序,所以theout放應該是:

Alice Cooper 
Andrew Hawking 
Stephen Hawking 
Jean Smith 
John Smith 

這裏是我的代碼:

#include <iostream> 
#include <stdio.h> 
#include <math.h> 
#include <cstdlib> 
#include <cstring> 
#include <ctype.h> 

using namespace std; 

//Identify space in a line 
int locateLastName (char name[][20], int i, int j) { 
    int locate = 0; 

    while (name[i][j] && locate == 0) { 
     if (isspace(name[i][j])) { 
      locate = 1; 
     } 
     j++; 
    } 
    return j; 
} 

int main(int argc, const char * argv[]) { 
    int x = atoi(argv[1]); //the number of names 
    char name[x][20]; //names in 2d array 
    char nameCopy[20]; //for bubble sort 

    //get the input names 
    for (int i = 0; i < x; i++) { 
     cin.getline(name[i],20); 
    } 

    //bubble sort the last name 
    for (int i = 0; i < x-1; i++) { 
     for (int j = 0; j < x-1; j++) { 
      int a = locateLastName(name, j, 0); 
      int b = locateLastName(name, j+1, 0); 

      int haveChange = 0; 
      while (name[j][a] && name[j+1][b] && haveChange == 0) { 
       if (name[j][a] > name[j+1][b]) { 
        strcpy(nameCopy, name[j]); 
        strcpy(name[j], name[j+1]); 
        strcpy(name[j+1], nameCopy); 

        haveChange = 1; 
       } 
       a++; 
       b++; 
      } 
     } 
    } 

    int line = 0; 
    while (line < x) { 
     cout << name[line] << endl; 
     line++; 
    } 
    return 0; 
} 

然而,在執行我的程序後產生以下結果:

./Sort-names 5 
Andrew Hawking ->input 
John Smith 
Stephen Hawking 
Alice Cooper 
Jean Smith 

John Smith  ->output 
Andrew Hawking 
Jean Smith 
Stephen Hawking 
Alice Cooper 

誰能幫我找到了這個錯誤,我不知道什麼是錯的。

+2

最好的方法是先使用調試程序遍歷代碼,然後檢查代碼在哪裏出現意外路徑。 –

+0

使用'string','vector'和'sort' – BLUEPIXY

+0

除了@ BLUEPIXY的建議,不要使用'atoi',而要使用'std :: stoi',不要使用專有的GCC變長數組,使用'cin.getline'但是'std :: getline',不要使用多維數組......基本上,不要使用所有這些錯誤的部分,因爲它們使得難以解決程序的真正問題邏輯。 –

回答

1

這種情況下的標準建議是使用調試器並找出發生了什麼問題。

國際海事組織,在這樣的情況下,這是相當差的建議。即使你調試了代碼並糾正了你觀察到的問題,它仍然會是幾個月左右你不會喜歡的代碼(我希望)。爲了長話短說,你沒有很好地使用語言和標準庫 - 你正在做很多工作來複制它已經準備好的功能,並且你可以使用它,沒有特別好的理由,重新使用一個特定編譯器的一些非標準(和不可移植的)擴展。

我可能會做更多的事情是這樣的:

#include <string> 
#include <iostream> 
#include <algorithm> 
#include <vector> 

// We'll use this a little later: just "eat" all the leading white-space 
// from a stream. 
std::istream &eat_whitespace(std::istream &is) { 
    char ch; 
    while (isspace(is.peek())) 
     is.get(ch); 
    return is; 
} 

// define a class to store, read, write, and compare people's names: 
class name { 
    std::string first; 
    std::string last; 
public: 
    // Define how to read a name from a stream: 
    friend std::istream &operator>>(std::istream &is, name &n) { 
     is >> n.first; 
     eat_whitespace(is); 
     return std::getline(is, n.last); 
    } 

    // likewise, how to write a name to a stream: 
    friend std::ostream &operator<<(std::ostream &os, name const &n) { 
     return os << n.first << ' ' << n.last; 
    } 

    // Define how to compare two names. This will compare first by last name, 
    // then if those are equal, first names: 
    bool operator<(name const &other) const { 
     if (other.last < last) 
      return false; 
     if (last < other.last) 
      return true; 
     return first < other.first; 
    } 
}; 

int main() { 
    // Read the names from a file into a vector: 
    std::vector<name> names { std::istream_iterator<name>(std::cin), 
     std::istream_iterator<name>() }; 

    // Sort them: 
    std::sort(names.begin(), names.end()); 

    // Write out the results: 
    for (auto const &n : names) 
     std::cout << n << "\n"; 
} 

也許這裏的一個最重要的一點是具有封裝在一個name所有的「知識」到name類。這讓程序的其餘部分只是讀取,比較和寫作name作爲一個完整的東西,而不是處理存儲名稱的所有內部細節(以及此類)。程序的其餘部分不關心(或需要知道)任何關於name如何在內部工作的內容。

另請注意,它是如何分解成多個單獨的功能,而不是幾乎所有的功能都在一個巨大的功能。在這種情況下,每個功能都非常小而且簡單(並且其目的很簡單),幾乎所有的功能幾乎乍一看都是非常明顯的。

接下來就是最後一部分:盡我們所能去做標準庫。就最明顯的例子來說,它已經有了用來排序的代碼 - 我們不需要編寫自己的代碼。

相關問題