SA-MP服务器PAWN模式读取vaults.cfg文件异常问题求助
我帮你梳理了问题的核心原因,以及对应的修复方案:
问题根源:配置文件格式不匹配代码逻辑
你的LoadVaults函数设计逻辑是每行读取一个金库的完整配置,也就是每次fread读取一行,然后将这行按逗号分割为8个字段(对应vID到vVW的8个属性),赋值给VaultInfo的一个元素。
初始配置的问题
你最初的vaults.cfg把所有7个金库的配置数据都挤在了同一行里:
0,4,2492.2615,-1702.3912,1018.3438,0,0,21,5,2332.6660,-1142.7737,1054.2969,0,0,32,6, 508.3405,-81.3647,998.9609,0,0,13,7,508.3405,-81.3647,998.9609,0,0,44,8,-223.3711,1411.0023,27.7734,0,0,15,9,-223.3711,1411.0023,27.7734,0,0,26,10,508.3405,-81.3647,998.9609,0,0,3
这会导致:
- 第一次
fread就读取了整个文件内容,split后得到的数组包含了所有7个金库的56个字段值,此时只有前8个值会被正确赋值给VaultInfo[0]。 - 后续循环中,
fread无法读取到新的内容(文件已经到末尾),strFromFile2为空字符串,分割后所有字段都是空值,调用strval/floatstr会返回0,导致VaultInfo[1]到VaultInfo[6]的所有属性都变成错误的默认值,这就是你看到的读取异常。
新配置正常的原因
你更换后的vaults.cfg应该是每行对应一个金库的8个字段数据(即使粘贴的排版看起来混乱,实际是每行一个完整的金库条目)。这样每次fread读取一行正好对应一个金库的配置,循环7次后所有数据都能正确赋值,所以结果正常。
修复方案
1. 修正配置文件格式
把vaults.cfg改成每行一个金库的配置,每行严格包含8个逗号分隔的值,顺序对应vID, vFaction, vPosX, vPosY, vPosZ, vCash, vDrugs, vVW,示例如下:
0,4,2492.2615,-1702.3912,1018.3438,0,0,21 5,2332.6660,-1142.7737,1054.2969,0,0,32,6 6,508.3405,-81.3647,998.9609,0,0,13,7 7,508.3405,-81.3647,998.9609,0,0,44,8 8,-223.3711,1411.0023,27.7734,0,0,15,9 9,-223.3711,1411.0023,27.7734,0,0,26,10 10,508.3405,-81.3647,998.9609,0,0,3
2. 优化代码的鲁棒性
原代码没有检查fread是否成功,也没有处理空行或字段不足的情况,容易出现错误。可以修改成更健壮的版本:
forward LoadVaults(); public LoadVaults() { new arrCoords[9][64], strFromFile2[256], File: file = fopen("vaults.cfg", io_read); if (file) { new idx = 0; // 同时检查数组容量和读取状态 while (idx < sizeof(VaultInfo) && fread(file, strFromFile2)) { // 跳过空行 if (strlen(strFromFile2) == 0) continue; split(strFromFile2, arrCoords, ','); // 检查是否有足够的字段(至少8个) if (arrCoords[7][0] == EOS) { printf("Warning: Invalid vault data at line %d (missing fields)", idx+1); idx++; continue; } // 赋值并打印 VaultInfo[idx][vID] = strval(arrCoords[0]); VaultInfo[idx][vFaction] = strval(arrCoords[1]); VaultInfo[idx][vPosX] = floatstr(arrCoords[2]); VaultInfo[idx][vPosY] = floatstr(arrCoords[3]); VaultInfo[idx][vPosZ] = floatstr(arrCoords[4]); VaultInfo[idx][vCash] = strval(arrCoords[5]); VaultInfo[idx][vDrugs] = strval(arrCoords[6]); VaultInfo[idx][vVW] = strval(arrCoords[7]); printf("VaultID %d FactionNUM %d, PosX %f, PosY %f, PosZ %f, Cash %d, Drugs %d, VW %d", VaultInfo[idx][vID], VaultInfo[idx][vFaction], VaultInfo[idx][vPosX], VaultInfo[idx][vPosY], VaultInfo[idx][vPosZ], VaultInfo[idx][vCash], VaultInfo[idx][vDrugs], VaultInfo[idx][vVW]); idx++; } fclose(file); // 提示未读取足够条目的情况 if (idx < sizeof(VaultInfo)) { printf("Warning: Only %d vaults loaded, expected %d", idx, sizeof(VaultInfo)); } } else { printf("Error: Failed to open vaults.cfg file!"); } return 1; }
这个版本会:
- 跳过空行
- 检查每行的字段数量是否足够
- 在文件读取完毕或数组填满时停止循环
- 打印错误/警告信息帮助排查问题
内容的提问来源于stack exchange,提问作者Nun

