字符串格式 %80[^,] 在 C 中是什么意思?
What does the string format %80[^,] mean in C?
给定以下几行:
char szInline[80];
char szDescription[80] = { NULL };
float fCost = 0;
sscanf (szInline, "%80[^,], %f", szDescription, &fCost);
%80[^,] 有什么作用?
读取最多 80 个字符直到下一个 ,
逗号。
顺便说一句,szDescription
缓冲区太小了 1。
以下是 sscanf(szInline, "%80[^,], %f", szDescription, &fCost)
的步骤:
sscanf
将 1
和 80
之间不同于 ,
的字符解析为数组 szDescription
,
- 如果成功,则它期望匹配
,
个字符;
- 如果找到,它将忽略任何白色space字符(包括
'\n'
);
- if 最后尝试将浮点数表示形式转换为
float
类型的变量 fCost
。
- 它将 return 成功转换的次数或
EOF
是早期失败的情况。
里面有潜在的问题:
- 目标数组
szDescription
对于 80 个字符加上一个 '[=23=]'
终止符来说太短了,但幸运的是,输入数组 szInline
的长度也是 80。如果它包含一个正确的字符串,最多 79
个字符将被 sscanf
匹配,因此不会发生溢出。在这种特殊情况下实际上不需要大小说明符。
-
,
之后的 space 是多余的。 %f
总是忽略前导白色space.
注意 sscanf()
将 return EOF
在此输入上:,1
因为有 no 个字符不同于 ,
从输入字符串的开头开始解析。即使是高级 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] = '[=10=]';
if (sscanf(szInline + len, ",%f", &fCost) != 1) {
/* conversion error: no `,` or no number past it */
...
}
sscanf()
有很多怪癖,众所周知,除了最琐碎的解析任务外,很难正确使用它。很少使用的标准函数 strspn()
和 strcspn()
是有用的替代方法。
给定以下几行:
char szInline[80];
char szDescription[80] = { NULL };
float fCost = 0;
sscanf (szInline, "%80[^,], %f", szDescription, &fCost);
%80[^,] 有什么作用?
读取最多 80 个字符直到下一个 ,
逗号。
顺便说一句,szDescription
缓冲区太小了 1。
以下是 sscanf(szInline, "%80[^,], %f", szDescription, &fCost)
的步骤:
sscanf
将1
和80
之间不同于,
的字符解析为数组szDescription
,- 如果成功,则它期望匹配
,
个字符; - 如果找到,它将忽略任何白色space字符(包括
'\n'
); - if 最后尝试将浮点数表示形式转换为
float
类型的变量fCost
。 - 它将 return 成功转换的次数或
EOF
是早期失败的情况。
里面有潜在的问题:
- 目标数组
szDescription
对于 80 个字符加上一个'[=23=]'
终止符来说太短了,但幸运的是,输入数组szInline
的长度也是 80。如果它包含一个正确的字符串,最多79
个字符将被sscanf
匹配,因此不会发生溢出。在这种特殊情况下实际上不需要大小说明符。 -
,
之后的 space 是多余的。%f
总是忽略前导白色space.
注意 sscanf()
将 return EOF
在此输入上:,1
因为有 no 个字符不同于 ,
从输入字符串的开头开始解析。即使是高级 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] = '[=10=]';
if (sscanf(szInline + len, ",%f", &fCost) != 1) {
/* conversion error: no `,` or no number past it */
...
}
sscanf()
有很多怪癖,众所周知,除了最琐碎的解析任务外,很难正确使用它。很少使用的标准函数 strspn()
和 strcspn()
是有用的替代方法。