考虑以下几行:
char szInline[80];
char szDescription[80] = { NULL };
float fCost = 0;
sscanf (szInline, "%80[^,], %f", szDescription, &fCost);
%80 [^,]做什么?
答案 0 :(得分:4)
最多可读取80个字符,直到下一个,
逗号。
顺便说一下,szDescription
缓冲区太小了1。
答案 1 :(得分:1)
以下是sscanf(szInline, "%80[^,], %f", szDescription, &fCost)
的步骤:
sscanf
会在1
和80
个不同于,
的字符之间解析为数组szDescription
,,
字符; '\n'
); fCost
类型的变量float
。EOF
是早期失败的情况。那里存在潜在的问题:
szDescription
对于80个字符和'\0'
终结符来说太短了,但幸运的是,输入数组szInline
的长度也是80.如果它包含正确的字符串,最多79
个字符将与sscanf
匹配,因此不会发生溢出。在这种特殊情况下,实际上不需要大小说明符。,
之后的空格是多余的。 %f
始终忽略前导空格。请注意sscanf()
将在此输入上返回EOF
:,1
因为没有字符与,
不同,需要从中解析输入字符串的开头。即使是高级C程序员也常常忽略这种特殊情况。
如果您想在,
之前接受可能为空的字符串,则无法直接使用sscanf()
,但您可以使用此字符:
/* compute the length of the initial sequence upto `,` if any */
size_t len = strcspn(szInline, ",");
/* len < 80 because sizeof(szInline) == 80 */
/* copying the initial string */
memcpy(szDescription, szInline, len);
szDescription[len] = '\0';
if (sscanf(szInline + len, ",%f", &fCost) != 1) {
/* conversion error: no `,` or no number past it */
...
}
sscanf()
有许多怪癖,除了最琐碎的解析任务之外,很难正确地使用它。很少使用标准函数strspn()
和strcspn()
是有用的替代方案。