C语言的scanf在使用char指针时不能正常工作。

问题描述 投票:0回答:2

我试图解析一个 FEN 在C语言中使用scanf,我有以下代码。

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字符串从a改成了a 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 chess
2个回答
2
投票

问题是你忽略了一点,即 C 字符串是空头的。.

你的声明

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

不留余地 '\0' 在从FEN中读取这些字符串后,将其附加在这些字符串的末尾。

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

这将解决这个问题。

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

1
投票

castle[4] 储存 "KQkq "这个字符串是不够的,没有空间来存放 "KQkq"。\0的时候,这将触发未定义的行为。sscanf() 写道 \0 在数组结束后,设置 castle的长度到 起码 5应该可以解决这个错误。


0
投票

问题在于分配 castle[4] 只有4个字符。 然后用 "KQkq",一个4个字符的字符串填充。 它看起来足够宽,但你可以读到 此处在转换指定符 "s "处。 总是在匹配的字符之外存储一个空字符 (所以参数数组必须至少有宽度+1字符的空间) https:/en.cppreference.comwciofscanf。


0
投票

可能Castle会覆盖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;
}
© www.soinside.com 2019 - 2024. All rights reserved.