【C++】_findfirst错误记录

在32位系统下正常运行的_findfirst方法,在迁移到64位系统时出现崩溃。问题源于_findfirst实际调用_findfirst64i32,其返回值为intptr_t类型。在64位系统中,如果用long类型接收intptr_t,会导致数据不匹配,文件句柄错误,进而引起程序崩溃。解决方案是确保将_findfirst的返回值类型定义为intptr_t,以适应不同平台的指针类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目背景

        目前在项目中用到了_findfirst方法来获取文件夹中的文件列表,使用_findfirst来获取文件句柄,在32位系统下可以正常运行,但是迁移到64位系统下,获取文件列表的函数直接崩溃。

问题的原因

        经过查看_findfirst源码发现,_findfirst宏定义实际上是函数_findfirst64i32()的宏定义_findfirst64i32()函数原型:

intptr_t _findfirst64i32(
    _In_ char const* _FileName, 
    _Out_ struct _finddata64i32_t* _FileData
);

        这个我们发现,该函数的返回值实际上是intptr_t类型,从这个发现了问题所在。原来在代码中获取_findfirst64i32返回值时只用了long类型来接受。而intptr_t类型在不同的平台上定义了不同类型的值,如果在64位系统上使用long类型来接受intptr_t的值会发生数据“分割”,导致文件句柄的值发生变化(相当于指针指向了一个未知的区域),对这个指针的任何操作都会发生崩溃。

#define _WIN64 
    typedef __int64 intptr_t; 
#else 
    typedef int intptr_t;

解决方案

  1. 将_findfrist函数的返回值类型定义成intptr_t
  2. 在不同的平台上使用不同的指针类型
假设我们将游戏记录保存在名为game_records.txt的文本文件中,每条记录占据一行,格式为“玩家1(底分)vs玩家2(底分)vs玩家3(底分):出牌顺序:玩家1->玩家2->玩家3;出牌情况:...;胜利者:玩家2”,则可以使用以下代码读取游戏记录: ```cpp #include <fstream> #include <string> #include <vector> #include <iostream> using namespace std; struct GameRecord { vector<pair<string, int>> players; // 玩家列表,存储玩家姓名和底分 vector<string> playOrder; // 出牌顺序 string playRecord; // 出牌情况 string winner; // 胜利者 }; int main() { ifstream ifs("game_records.txt"); // 打开文件 if (!ifs) { // 判断文件是否成功打开 cout << "Failed to open file!" << endl; return 1; } vector<GameRecord> gameRecords; // 存储游戏记录 string line; while (getline(ifs, line)) { // 逐行读取文件内容 GameRecord record; string playerName; int playerScore; // 读取玩家列表 size_t pos = 0; while ((pos = line.find("(")) != string::npos) { playerName = line.substr(0, pos); line = line.substr(pos + 1); pos = line.find(")"); playerScore = stoi(line.substr(0, pos)); record.players.push_back(make_pair(playerName, playerScore)); line = line.substr(pos + 1); } // 读取出牌顺序 pos = line.find("出牌顺序:"); line = line.substr(pos + 5); pos = line.find(";"); while (pos != string::npos) { record.playOrder.push_back(line.substr(0, pos)); line = line.substr(pos + 1); pos = line.find(";"); } // 读取出牌情况 pos = line.find("出牌情况:"); record.playRecord = line.substr(pos + 5); // 读取胜利者 pos = line.find("胜利者:"); record.winner = line.substr(pos + 4); gameRecords.push_back(record); } ifs.close(); // 关闭文件 // 使用读取到的数据 cout << "Game records:" << endl; for (auto record : gameRecords) { cout << "Players: "; for (auto player : record.players) { cout << player.first << "(" << player.second << ") "; } cout << endl; cout << "Play order: "; for (auto player : record.playOrder) { cout << player << "->"; } cout << endl; cout << "Play record: " << record.playRecord << endl; cout << "Winner: " << record.winner << endl; cout << endl; } // ... return 0; } ``` 在上面的代码中,我们使用ifstream类打开了名为game_records.txt的文件,并逐行读取了其中的内容。我们将每条记录存储在一个GameRecord结构体中,并将所有记录存储在gameRecords向量中。最后,我们输出了读取到的数据。如果文件打开失败,我们就输出一段错误信息。最后,我们关闭了文件。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值