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]
额外的 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;
}
我正在尝试在 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]
额外的 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;
}