我试图解析一个 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 字符串是空头的。.
你的声明
char side, pos[128], castle[4], enpas[2];
不留余地 '\0'
在从FEN中读取这些字符串后,将其附加在这些字符串的末尾。
因此,它是未定义的行为。
这将解决这个问题。
char side, pos[129], castle[5], enpas[3];
castle[4]
储存 "KQkq "这个字符串是不够的,没有空间来存放 "KQkq"。\0
的时候,这将触发未定义的行为。sscanf()
写道 \0
在数组结束后,设置 castle
的长度到 起码 5应该可以解决这个错误。
问题在于分配 castle[4]
只有4个字符。 然后用 "KQkq",一个4个字符的字符串填充。 它看起来足够宽,但你可以读到 此处在转换指定符 "s "处。 总是在匹配的字符之外存储一个空字符 (所以参数数组必须至少有宽度+1字符的空间) https:/en.cppreference.comwciofscanf。
可能Castle会覆盖pos(堆栈从下到上),所以,可以试试以下方法 castle[4]
到 castle[5]
多给 NULL
和 enpass[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;
}