无法似乎让sscanf()按照我想要的方式工作

3

我正在使用AT命令编写程序,但在使用sscanf()函数解析时遇到了问题。

例如,如果我使用以下命令:

"AT\r\r\nOK\r\n"

我想要: * 在第一次调用时,只获取“AT”部分,丢弃后面的“\r”字符,并知道到目前为止已经读取了多少个字符。 * 在第二次调用时,只获取“OK”部分,丢弃在“OK”字符串之前和之后出现的“\r\n”字符,并知道到目前为止已经读取了多少个字符。
我编写了以下的sscanf函数调用:
index = 0;
sscanf(buffer + index, "%*[\r\n]%[^\r]\r%*[\n]%n", new_buffer, &count);
index += count;

为什么它不会返回我请求的字符串?我做错了什么?
提前感谢您的帮助。
2个回答

1
也许问题出在sscanf如何处理空格字符,例如回车和换行符,以及您的期望。 sscanf需要忽略(跳过)前导空格。
另一个问题可能是回车符从未到达您的缓冲区。 C实现需要将\r\n映射到\n(用于文本流)的输入上。

首先,我想感谢Jens的帮助。我认为sscanf()对回车或换行符并没有像普通字符一样的处理方式。 此外,内容按照我上面写的方式进入缓冲区(在阅读您的回复后,我已经检查了缓冲区的内容)。不知道还可能是什么问题.. 我传递给函数的标记似乎没问题,对吧? - LinkOfTime

0

让我们来分析这个格式:

sscanf(buffer + index, "%*[\r\n]%[^\r]\r%*[\n]%n", new_buffer, &count);

首先,跳过初始序列中的'\r''\n'字符(%*[\r\n])。然后扫描并存储到new_buffer中,直到下一个'\r'的字符(%[^\r])。
接下来,跳过所有后续的空格字符(\r)。现在已经消耗了"OK"'O'之前的部分。
然后,忽略到下一个换行符的所有字符(%*[^\n])。现在只剩下最后一个未被消耗的换行符。然后将消耗的字符数存储在count中。
你的问题是,格式字符串中的任何空格字符(当然不包括字符集外的空格)都会消耗该位置出现的整个(可能为空的)空格字符序列。格式字符串中的\r并不意味着"一个字符'\r'",它意味着"这里的所有空格"。
如果你的格式是固定的,你可以通过使其扫描(并忽略)任何字符(在你的情况下保证是一个'\r')来修复它。
sscanf(buffer + index, "%*[\r\n]%[^\r]%*c%*[\n]%n", new_buffer, &count);

感谢Daniel的帮助。虽然我不同意你写的一些东西。我同意你写的第一段。但是,在第二段中,我认为(\r)并不会使函数跳过所有后面的空格字符。它只会跳过一个单独的\r字符。这就像写:sscanf(buffer,"%[^:]:", 这只会让它跳过一个':'字符,而不是所有的字符。然后我添加了(%[^\n])部分,因为有些命令行以"\r"结尾,有些以"\r\n"结尾,我想跳过两者。 - LinkOfTime
问题在于令牌末尾的%n会将0放入计数器中,并且没有任何内容被读入new_buffer。 - LinkOfTime
好的,我再次测试了一下,我同意你所说的。它确实对 '\r' 字符和 ':' 字符有不同的处理方式。问题是,我该如何修复它?例如,在这段文本中:"AT\r\r\nOK\r\n"我想第一次读取 "AT\r",第二次读取 "\r\nOK\r\n"。我应该如何将跟随它的 '\r\n' 与 '\r' 分离开? - LinkOfTime
这取决于你想要什么以及提供了什么。假设输入缓冲区恰好包含"AT\r\r\nOK\r\n"。如果你想要存储“AT”并消耗后面的'\r'但不存储它,忽略一个字符 - %*c - 就可以实现。如果你想要存储"AT\r",那么使用字段宽度就可以实现。然而,如果你想要对第二个扫描使用完全相同的格式字符串,那么这将是有问题的。如果你的需求足够复杂,编写自己的解析函数可能比获取正确的sscanf格式更容易。你的确切要求是什么? - Daniel Fischer
如果您使用%s格式(在第一个非空白序列后停止,停留在下一个空格处),则可能的初始"\r\n"将被跳过;或者,如果您想要扫描包含空格的文本,则可以使用" %[^\r\n]%n";初始空格使sscanf跳过可选的前导空格,然后读取直到下一个'\r''\n'或终止0之间的所有字符。由于%n,读取的字符数将被存储,因此您知道扫描下一行的偏移量。如果您使用" %[^\r\n] %n",尾随空格也将被消耗。 - Daniel Fischer
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接