请注意,sscanf() 默认情况下很大程度上会忽略空白。格式字符串中的空格匹配零个或多个空格字符——空格、制表符、换行符。除了三个转换规范之外,所有的转换规范都忽略了前导空格——三个例外是%c、%[…](扫描集)和%n——所以对于格式字符串中的所有空格,空格和制表符都不应该影响转换,除非在第一个 { 之前有空格(您可以通过在{ 之前的格式字符串中添加一个空格来管理)。因此,问题可能不在于sscanf(),而在于数据中的字符。
如果您使用fgets() 读取数据,则需要将多行累积到单个字符串缓冲区中。如果您将sscanf() 替换为scanf() 或fscanf(),那么您的格式字符串将根据需要读取换行符(但两者都会在大括号} 之后留下任何换行符以供将来的输入操作读取)。当sscanf() 处理数据时,字符串必须包含所有必需的字符,名义上一直到结尾},但到第六个数字的最后一位就足够了。
鉴于此代码 - 第三个字符串表示您所说的内容在您的第三个多行数据中(我假设前导 1) 和 2) 加上空格是问题中的噪音,因为格式字符串不会尝试解析这些):
#include <stdio.h>
static char *data[] =
{
"{[0;0],[19;10],[0;10]}",
"{ [ 0 ; 0], [12;0],[0 ;10] }",
"{\n[\n0\n;\n15\n]\n, [ 112 ; 0 ] ,[112;15]}\n",
};
enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
int main(void)
{
for (int i = 0; i < NUM_DATA; i++)
{
printf("String: @@%s@@@\n", data[i]);
double x_1 = -9.9, y_1 = -9.9;
double x_2 = -9.9, y_2 = -9.9;
double x_3 = -9.9, y_3 = -9.9;
int rc = sscanf(data[i], "{ [ %lf ; %lf ] , [ %lf ; %lf ] , [ %lf ; %lf ] }",
&x_1, &y_1, &x_2, &y_2, &x_3, &y_3);
printf("rc = %d: ", rc);
printf(" 1 = (%.1lf,%.1lf)", x_1, y_1);
printf(" 2 = (%.1lf,%.1lf)", x_2, y_2);
printf(" 3 = (%.1lf,%.1lf)", x_3, y_3);
putchar('\n');
}
return 0;
}
我得到了输出:
String: @@{[0;0],[19;10],[0;10]}@@@
rc = 6 1 = (0.0,0.0) 2 = (19.0,10.0) 3 = (0.0,10.0)
String: @@{ [ 0 ; 0], [12;0],[0 ;10] }@@@
rc = 6 1 = (0.0,0.0) 2 = (12.0,0.0) 3 = (0.0,10.0)
String: @@{
[
0
;
15
]
, [ 112 ; 0 ] ,[112;15]}
@@@
rc = 6 1 = (0.0,15.0) 2 = (112.0,0.0) 3 = (112.0,15.0)
如您所见,所有三个扫描操作均成功。这表明您认为第三个(多行)字符串并不是您实际得到的。
我建议对失败的数据进行逐字节转储,以查看问题出在哪里。另请注意,我从sscanf() 捕获并打印了返回值;这将帮助您确定错误字符的位置。请注意,sscanf() 无法告诉您它无法匹配格式字符串中的最终 ] 或 } — 您永远不会知道它们是否与当前格式匹配。