【问题标题】:C sscanf not working correctly with char pointerC sscanf 无法与 char 指针一起正常工作
【发布时间】:2020-09-10 06:11:07
【问题描述】:

我正在尝试在 C 中使用 sscanf 解析 FEN。我有以下代码:

int main() {
  char side, pos[128], castle[4], enpas[2];
  int halfMove, fullMove;
  const char fen[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
  const int res = sscanf(fen, "%s %c %s %s %d %d", pos, &side, castle, enpas, &halfMove, &fullMove);
  printf("%d\n", res);
  printf("%s %c %s %s %d %d\n", pos, side, castle, enpas, halfMove, fullMove);
  return 0;
}

当我运行此代码时,我得到以下预期结果:

6
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

但是,当我将 FEN 字符串从 char 数组更改为 char 指针时,像这样

const char *fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";

我得到以下结果:

6
 w KQkq - 0 1

好像字符串的第一部分被忽略了。为什么会这样?我正在使用 GCC 10.1.0。

【问题讨论】:

    标签: c scanf c-strings chess


    【解决方案1】:

    问题是您错过了 C 字符串是空终止的这一点。

    您的声明

    char side, pos[128], castle[4], enpas[2];
    

    在从 FEN 读取这些字符串后,不会在这些字符串的末尾附加空间。

    因此,这是未定义的行为。

    这样就可以解决问题了:

    char side, pos[129], castle[5], enpas[3];
    

    【讨论】:

      【解决方案2】:

      castle[4] 不足以存储字符串“KQkq”,\0 没有空间,这会在sscanf() 在数组末尾写入\0 时触发未定义的行为。将castle 的长度设置为至少 5 应该可以修复错误。

      【讨论】:

        【解决方案3】:

        问题是分配 castle[4] 时只有 4 个字符。
        然后用 4 个字符的字符串“KQkq”填充它。
        它看起来足够宽,但你可以阅读 here 在转换说明符“s”处:

        除了匹配的字符之外,始终存储一个空字符(因此
        参数数组必须有空间至少容纳 width+1 个字符)
        https://en.cppreference.com/w/c/io/fscanf

        【讨论】:

          【解决方案4】:

          可能城堡会覆盖 pos(堆栈从下到上)所以,试试这个 castle[4]castle[5] 额外一个 NULLenpass[2]enpass

          看这个:

          #include<stdio.h>
          
          int main() 
          {
            char side, pos[128], castle[5], enpas;
            int halfMove, fullMove;
          
            const char *fen  = "rnbqkbnrpppppppp8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
            const int   res  = sscanf(fen, "%s %c %s %c %d %d", pos, &side, castle, &enpas, &halfMove, &fullMove);
          
            printf("%d\n", res);
            printf("%s %c %s %c %d %d\n", pos, side, castle, enpas, halfMove, fullMove);
          
            return 0;
          }
          

          【讨论】:

          • 堆栈分配的方向并没有规定编译器如何在堆栈帧中布置对象。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-14
          • 2020-08-19
          • 2013-02-06
          • 2019-02-02
          • 2021-10-15
          相关资源
          最近更新 更多