【发布时间】:2016-08-20 04:47:01
【问题描述】:
我想解析一个特定的行。因此,我编写了以下代码来测试逻辑,但我可能理解错误:
typedef struct vers
{
char tu8UVersion[5];
char tu8UCommit[32];
}tst_prg_versions;
int main(int argc, char **argv)
{
tst_prg_versions lstVer;
char buf1[32];
char buf2[32];
char str[] = "BOARD-VERS-v1.0.0-git+9abc12345a";
sscanf(str, "BOARD-VERS-v%5s-git+%s", lstVer.tu8UVersion, lstVer.tu8UCommit);
printf("vers='%s'\n", lstVer.tu8UVersion);
printf("commit='%s'\n", lstVer.tu8UCommit);
sscanf(str, "BOARD-VERS-v%5s-git+%s", buf1, buf2);
printf("vers='%s'\n", buf1);
printf("commit='%s'\n", buf2);
return 0;
}
一旦执行,它就会返回:
vers='1.0.09abc12345a'
commit='9abc12345a'
vers='1.0.0'
commit='9abc12345a
为什么第一个 vers 等于 1.0.09abc12345a 而不是 1.0.0?
【问题讨论】:
-
@user3121023 感谢您的回答!为了避免这种问题,将结构变量声明为 char * 更好吗? sscanf 负责内存分配
-
scanf不会为你分配内存;您必须提供足够大小的缓冲区。 -
printf("vers='%s'\n", lstVer.tu8UVersion);不仅是错误的,而且是未定义的行为。 -
@MOehm 根据这个话题stackoverflow.com/questions/15414022/…scanf 是可以分配内存的吧?
-
是的,但这似乎是一个 GNU 扩展,因此不可移植。在堆上为五个字母的字符串分配空间也不是一个好主意,以便以后必须释放它。更好的方法是使缓冲区稍大,例如
[10],然后使用%9[^-]扫描不是连字符的所有内容。这将使您能够扫描具有两位数的版本。 (字符串格式%s将所有内容扫描到下一个空格。或者,将数字扫描为数字。您还应该测试sscanf的返回值。)