C sscanf 不能正确使用 char 指针

C sscanf not working correctly with char pointer

我正在尝试在 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.

castle[4] 不足以存储字符串 "KQkq",[=11=] 没有 space,这会在 sscanf() 写入时触发未定义的行为[=11=] 数组结束后。将 castle 的长度设置为 至少 5 应该可以修复错误。

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

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

问题是您忽略了 C 字符串以 null 结尾

你的声明

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

在从 FEN 读取这些字符串后,'[=12=]' 不会将 space 附加到这些字符串的末尾。

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

这将解决问题:

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

可能城堡会覆盖 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;
}