字符串格式%80 [^,]在C中的含义是什么?

时间:2016-07-27 00:05:39

标签: c string-formatting scanf

考虑以下几行:

char szInline[80];
char szDescription[80] = { NULL };
float fCost = 0;
sscanf (szInline, "%80[^,], %f", szDescription, &fCost);

%80 [^,]做什么?

2 个答案:

答案 0 :(得分:4)

最多可读取80个字符,直到下一个,逗号。

顺便说一下,szDescription缓冲区太小了1。

答案 1 :(得分:1)

以下是sscanf(szInline, "%80[^,], %f", szDescription, &fCost)的步骤:

  • sscanf会在180个不同于,的字符之间解析为数组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()是有用的替代方案。