如何修改sscanf格式串以完整读取目标输入行?
解决sscanf读取制表符分隔字段的问题
你的问题出在格式串的两个关键错误上:
%[A-Z\(\)a-z0-9]s里的s是多余的——%[]本身就是完整的字符串转换说明,不需要额外加s。- 该字符集未包含空格,导致
visa payment (online)中的空格会让匹配提前终止,后续的制表符匹配失败,自然读不到最后一个字段。
针对你的制表符分隔输入,推荐两种可靠的格式串方案:
方案一:利用空白匹配任意分隔符
这种方案利用sscanf中空白字符(空格、制表符等)会匹配任意数量空白的特性,简化格式串:
sscanf(lineIn, "%d/%d %f %[^\t] %s", &month, &year, &amt, item, supplier);
%d/%d:正确解析01/05为月份和年份。%f:读取金额840.81。%[^\t]:读取所有字符直到遇到制表符,完美匹配包含空格和括号的visa payment (online)。%s:跳过前面的制表符,读取最后一个字段AFCU(%s会自动跳过前置空白,读取到换行符为止)。
方案二:明确跳过制表符(更严谨)
如果需要严格匹配制表符分隔,避免意外匹配空格分隔的情况,可以用%*[\t]跳过任意数量的制表符:
sscanf(lineIn, "%d/%d%*[\t]%f%*[\t]%[^\t]%*[\t]%[^\n]", &month, &year, &amt, item, supplier);
%*[\t]:读取制表符但不存储,跳过字段间的制表符(包括多个连续制表符)。%[^\n]:读取最后一个字段直到换行符,即使末尾有空白也能正确捕获(如果不需要末尾空白,可以换成%s)。
注意事项
- 确保
item和supplier数组的大小足够容纳对应字段内容,避免缓冲区溢出(比如定义为char item[128], supplier[64];)。 - 如果输入行末尾可能有换行符或多余空白,
%[^\n]会包含这些内容,若要过滤可以在格式串末尾添加%*[ \n](读取但不存储末尾空白和换行)。
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

