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

位图计算中的位移操作失效问题排查求助

CLI国际象棋程序位图显示问题:低位(如e2、a1)显示0的排查与修复

问题根源分析

你的问题核心来自两个关键错误:

  • 64位整数的32位格式化输出:用%x打印uint64_t类型,导致高位字节被截断,看起来值为0,但实际位图计算是正确的。
  • 输入处理的逻辑漏洞:fgets的换行符处理和合法性判断存在隐患,只是h8h7这类高位位置的位图值落在32位范围内,才没暴露问题。

细节拆解:

  1. 格式化输出错误:
    %x是32位无符号整数的格式符,而uint64_t是64位类型。比如e2对应的位图是0x8000000000000000ULL >> 12,结果为0x0008000000000000,它的低32位全是0,用%x输出就会显示为0;而h8对应的0x1(低32位有值)则能正常显示。

  2. 输入处理的隐患:

    • fgets读取输入时,若用户输入4个字符后回车,换行符会被读入缓冲区,导致strlen(input)变为5,触发check_valid_input的长度判断,返回空的Move结构体。
    • 重复定义Move结构体,属于冗余代码,会引发编译警告。
    • 使用tolower但未包含<ctype.h>头文件,存在未定义行为。

修复方案

1. 修正64位整数输出格式

引入<inttypes.h>头文件,使用标准跨平台的64位整数格式符PRIx64:

#include <inttypes.h>
// 替换原printf语句
printf("Hex: S-map: %" PRIx64 " E-map: %" PRIx64 "\n", input.s_map, input.e_map);

如果不想引入新头文件,也可以用%llx(GCC/Clang)或%lx(MSVC),但PRIx64是跨平台标准写法。

2. 修复输入处理逻辑

调整get_input和check_valid_input,正确处理换行符并细化合法性判断:

#include <string.h>
#include <ctype.h>

Move get_input() {
    char input[10]; // 扩大缓冲区避免截断
    printf("Enter the move eg='e2e4' : ");
    fgets(input, sizeof(input), stdin);
    
    // 移除换行符(如果存在)
    input[strcspn(input, "\n")] = '\0';
    printf("%s\n", input);
    
    if (check_valid_input(input)) {
        return (Move){0X0ULL, 0x0ULL};
    }
    return input_to_bitmap(input);
}

int check_valid_input(char* input) {
    if (strlen(input) != 4) {
        puts("Enter the move in a valid format.");
        return 1;
    }
    // 检查列范围(支持大小写)
    if (!((input[0] >= 'a' && input[0] <= 'h') || (input[0] >= 'A' && input[0] <= 'H'))) {
        puts("Invalid source column.");
        return 1;
    }
    if (!((input[2] >= 'a' && input[2] <= 'h') || (input[2] >= 'A' && input[2] <= 'H'))) {
        puts("Invalid target column.");
        return 1;
    }
    // 检查行范围
    if (input[1] < '1' || input[1] > '8') {
        puts("Invalid source rank.");
        return 1;
    }
    if (input[3] < '1' || input[3] > '8') {
        puts("Invalid target rank.");
        return 1;
    }
    return 0;
}

3. 其他代码优化

  • 删除重复的Move结构体定义。
  • 确保包含必要头文件:<ctype.h>(tolower)、<string.h>(strcspn/strlen)、<inttypes.h>(64位格式符)。

验证修复效果

修复后输入e2e4,会输出正确的64位十六进制值:

Enter the move eg='e2e4' : e2e4
e2e4
Hex: S-map: 8000000000000 E-map: 80000000000

内容的提问来源于stack exchange,提问作者Syntax Error12

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:02:03