2015-11-08 113 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如何在内部工作的内容。

另请注意,它是如何分解成多个单独的功能,而不是几乎所有的功能都在一个巨大的功能。在这种情况下,每个功能都非常小而且简单(并且其目的很简单),几乎所有的功能几乎乍一看都是非常明显的。

接下来就是最后一部分:尽我们所能去做标准库。就最明显的例子来说,它已经有了用来排序的代码 - 我们不需要编写自己的代码。

相关问题