RAD Studio 10.2中std::sort函数异常导致游戏高分系统开发受阻
嘿,我刚看完你的问题——在RAD Studio 10.2里做游戏高分模块时栽在std::sort的异常行为上了,对吧?先从你贴的代码说起,咱们一步步捋清楚可能的问题点,再给你靠谱的修复方案。
先说说现有代码的小隐患
你现在两次打开Highscore.txt来计数再读取,其实完全可以优化:读完行数后重置文件指针就行,不用重新打开,避免文件被其他进程锁定或者重复IO的开销。另外用new string[count]动态数组的话,记得最后要delete[] scores,不然游戏跑久了会内存泄漏,这点很重要。
std::sort异常的核心原因(RAD Studio里的常见坑)
你没贴完整的sort代码,但结合RAD Studio的编译器特性,大概率是这几个问题:
1. 比较函数不满足严格弱序
这是std::sort最容易触发未定义行为的坑!比如你要是写了return stoi(a) >= stoi(b)这种比较逻辑,就违反了严格弱序的要求——对于两个相等的元素,compare(a,b)和compare(b,a)必须都返回false。RAD Studio的STL实现对这个检查很严格,直接就会抛出异常或者崩溃。
正确的降序比较应该是:
bool compareScores(const string& a, const string& b) { return stoll(a) > stoll(b); // 用stoll避免整数溢出,严格大于满足弱序 }
2. 字符串转整数时的未捕获异常
如果Highscore.txt里有非数字内容(比如空行、空格、字母),stoi会直接抛出invalid_argument或者out_of_range异常,你没捕获的话,程序就会崩,看起来像是sort的问题,但根源是转数环节出错了。
3. 空数组/越界访问
如果count是0(比如文件为空),你还调用std::sort的话,就会触发异常;或者计数时把空行算进去了,导致数组里有空字符串,转数时出错。
修复后的完整代码示例
我给你改了更安全的版本,用vector代替动态数组,优化文件读取,加上异常捕获,彻底避免这些坑:
#include <fstream> #include <vector> #include <algorithm> #include <stdexcept> #include <string> #include <iostream> using namespace std; int main() { ifstream File("Highscore.txt"); if (!File.is_open()) { cerr << "Failed to open highscore file!" << endl; return 1; } int count = 0; string Line; // 先计数,同时过滤空行 while (getline(File, Line)) { if (!Line.empty()) { count++; } } // 重置文件状态和指针,不用重新打开 File.clear(); File.seekg(0, ios::beg); // 用vector自动管理内存,比new[]安全100倍 vector<string> scores; scores.reserve(count); // 预分配内存,提升性能 while (getline(File, Line)) { if (!Line.empty()) { scores.push_back(Line); } } File.close(); // 排序前先检查数组非空 if (!scores.empty()) { try { // 用lambda表达式写比较逻辑,简洁明了 sort(scores.begin(), scores.end(), [](const string& a, const string& b) { // 转成long long避免游戏高分溢出int范围 long long scoreA = stoll(a); long long scoreB = stoll(b); // 严格大于,满足严格弱序要求 return scoreA > scoreB; }); } catch (const invalid_argument& e) { // 处理无效的分数字符串,比如日志记录 cerr << "Invalid score in file: " << e.what() << endl; } catch (const out_of_range& e) { // 处理分数过大溢出的情况 cerr << "Score exceeds maximum value: " << e.what() << endl; } } // 这里可以把排序后的scores写回文件或者显示到游戏UI for (const auto& s : scores) { cout << s << endl; } return 0; }
调试小技巧
- 在RAD Studio里开调试模式,查看异常的调用栈,就能精准定位是转数环节还是sort内部出的问题;
- 先把读取到的
scores数组打印出来,确认所有分数都是有效的整数,再调用sort; - 检查
Highscore.txt的内容,确保每一行都是纯数字,没有空行或多余字符。
内容的提问来源于stack exchange,提问作者Samy Dressel

