You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用qsort排序C++结构体数组遇到的两个问题求助

问题排查:qsort排序student结构体出现的姓名匹配错误与截断问题

我想用qsort()对student结构体数组排序,规则是先按成绩升序,成绩相同再按学号升序,但遇到两个问题:

  • 成绩已按升序正确排序,但成绩和对应学生姓名不匹配
  • 部分学生姓名被截断(比如“Veronica”显示成“Ver”)

运行结果

Sorted by grades 
Ver Grade: 28
Alistair Grade: 68
Fred Grade: 70
Erin Grade: 75
Lesli Grade: 78
Belind Grade: 81
Sash Grade: 84
Tom Grade: 87
Aretha Grade: 98
Candy Grade: 100

原代码

#include <iostream>
#include <string>
using namespace std;

struct student {
    int grade;
    int studentID;
    string name;
};

const int ARRAY_SIZE = 10;
student studentArray[ARRAY_SIZE] = {
    {87, 10001, "Fred"},
    {28, 10002, "Tom"},
    {100, 10003, "Alistair"},
    {78, 10004, "Sasha"},
    {84, 10005, "Erin"},
    {98, 10006, "Belinda"},
    {75, 10007, "Leslie"},
    {70, 10008, "Candy"},
    {81, 10009, "Aretha"},
    {68, 10010, "Veronica"}
};


// Comparator Function 
int compareFunc(const void* voidA, const void* voidB)
{
    student* studentA = (student*) voidA;
    student* studentB = (student*) voidB;
    return (studentA->grade - studentB->grade);
}

int main()
{
    // Use qsort to sort an array of our student struct 
    qsort(studentArray, ARRAY_SIZE, sizeof(student), compareFunc);
    
    // First sort by grade
    cout << "Sorted by grades \n";
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        cout << studentArray[i].name << " Grade: " << studentArray[i].grade  << '\n';
    }
    
    // Second sort by student ID

}

问题根源

  1. qsort与std::string不兼容:qsort是C标准库函数,通过逐字节拷贝内存交换元素,但std::string是带资源管理的C++类(内部持有动态分配的字符数组),直接字节拷贝会导致浅拷贝问题——两个string对象指向同一块内存,后续操作触发未定义行为,表现为姓名与成绩不匹配、字符串截断损坏。
  2. 比较函数逻辑不完整:当前只实现了按成绩排序,未处理成绩相同时按学号升序的需求。

解决方法

方案1:用C++标准库std::sort(推荐)

std::sort是C++专属排序函数,能正确处理带构造/析构的类对象,类型安全且效率更高。修改后代码:

#include <iostream>
#include <string>
#include <algorithm> // 引入std::sort
using namespace std;

struct student {
    int grade;
    int studentID;
    string name;
};

const int ARRAY_SIZE = 10;
student studentArray[ARRAY_SIZE] = {
    {87, 10001, "Fred"},
    {28, 10002, "Tom"},
    {100, 10003, "Alistair"},
    {78, 10004, "Sasha"},
    {84, 10005, "Erin"},
    {98, 10006, "Belinda"},
    {75, 10007, "Leslie"},
    {70, 10008, "Candy"},
    {81, 10009, "Aretha"},
    {68, 10010, "Veronica"}
};

// 比较规则:先按成绩升序,成绩相同则按学号升序
bool compareStudents(const student& a, const student& b) {
    if (a.grade != b.grade) {
        return a.grade < b.grade;
    }
    return a.studentID < b.studentID;
}

int main()
{
    sort(studentArray, studentArray + ARRAY_SIZE, compareStudents);
    
    cout << "Sorted by grades (then student ID)\n";
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        cout << studentArray[i].name << " Grade: " << studentArray[i].grade 
             << " ID: " << studentArray[i].studentID << '\n';
    }
}

方案2:强制使用qsort(不推荐)

将std::string替换为C风格字符串(固定大小char[]),因为C风格字符串是普通内存块,qsort的字节拷贝不会出问题:

#include <iostream>
#include <cstring> // 引入C字符串操作函数
using namespace std;

struct student {
    int grade;
    int studentID;
    char name[20]; // 定义足够大的字符数组存储姓名
};

const int ARRAY_SIZE = 10;
student studentArray[ARRAY_SIZE] = {
    {87, 10001, "Fred"},
    {28, 10002, "Tom"},
    {100, 10003, "Alistair"},
    {78, 10004, "Sasha"},
    {84, 10005, "Erin"},
    {98, 10006, "Belinda"},
    {75, 10007, "Leslie"},
    {70, 10008, "Candy"},
    {81, 10009, "Aretha"},
    {68, 10010, "Veronica"}
};

// 比较函数:先按成绩升序,成绩相同按学号升序
int compareFunc(const void* voidA, const void* voidB)
{
    const student* studentA = static_cast<const student*>(voidA);
    const student* studentB = static_cast<const student*>(voidB);
    
    if (studentA->grade != studentB->grade) {
        return studentA->grade - studentB->grade;
    }
    return studentA->studentID - studentB->studentID;
}

int main()
{
    qsort(studentArray, ARRAY_SIZE, sizeof(student), compareFunc);
    
    cout << "Sorted by grades (then student ID)\n";
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        cout << studentArray[i].name << " Grade: " << studentArray[i].grade 
             << " ID: " << studentArray[i].studentID << '\n';
    }
}

内容的提问来源于stack exchange,提问作者あじうまい

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 19:57:52