如何修改fscanf语句以读取含空格字符串的制表符分隔行?
问题说明
现有C语言代码片段如下:
fscanf(input_file, "%s\t%d\t%d", line, &x, &y);
该代码意图读取一行制表符分隔的数据,待读取文件的内容格式示例为:
Double Cheese 4 10
其中“Double Cheese”与4、4与10之间均由制表符分隔。但原代码无法将包含空格的字符串“Double Cheese”完整存入line变量,需要调整代码实现需求。
问题根源
原代码中使用的%s格式说明符会读取连续的非空白字符,遇到空格、制表符或换行符就会停止解析,因此只能读取到“Double”,剩余的“Cheese”会留在输入缓冲区,导致后续的%d格式无法正确读取整数,引发数据解析错误。
解决方案
方法1:使用%[^\t]格式说明符替换%s
%[^\t]是一种扫描集格式,它会读取所有字符直到遇到制表符(\t)为止,刚好匹配需求中“制表符前的包含空格的字符串”场景。
调整后的代码:
// 建议指定读取长度,避免缓冲区溢出(假设line数组长度为256) fscanf(input_file, "%255[^\t]\t%d\t%d", line, &x, &y);
- 注意:必须为
%[^\t]指定最大读取长度(如示例中的255),长度值需比line数组的实际长度小1,预留空间存储字符串终止符\0,防止缓冲区溢出。 - 如果输入行开头存在空白字符,
%[^\t]会直接读取这些空白;若需要跳过开头空白,可在格式串前添加%*[ \n](忽略开头的空格和换行)。
方法2:先读取整行再拆分(更安全的方式)
先使用fgets读取完整的一行数据到缓冲区,再用sscanf拆分数据,这种方式可以避免fscanf因输入残留导致的解析问题,同时更易处理换行符等特殊情况。
示例代码:
char buffer[256]; if (fgets(buffer, sizeof(buffer), input_file) != NULL) { // 移除可能存在的换行符 buffer[strcspn(buffer, "\n")] = '\0'; // 拆分整行数据 sscanf(buffer, "%[^\t]\t%d\t%d", line, &x, &y); }
strcspn函数用于找到换行符的位置,将其替换为终止符,确保后续解析不受换行符影响。- 同样建议为
%[^\t]指定最大读取长度,避免缓冲区溢出。
内容的提问来源于stack exchange,提问作者Patrick Wong
相关产品推荐
相关产品推荐

