强制fscanf使用可能的空白
我有一个多行TSV文件,格式如下:强制fscanf使用可能的空白,c,whitespace,string-formatting,scanf,C,Whitespace,String Formatting,Scanf,我有一个多行TSV文件,格式如下: Type\tBasic Name\tAttribute\tA Long Description\n 如您所见,基本名称和描述都可以包含一些空格。我试图读入每一行并提取元素。现在,我把范围缩小到只提取基本名称。我的fscanf如下: fscanf(file_in, "%*[^ ]s\t%128[^ ]s\t%*[^ ]s\t%[^ ]s\n", name_string, desc_string); 这并不像我希望的那样有效,而且我在缩小误差方面遇到了困难。有
Type\tBasic Name\tAttribute\tA Long Description\n
如您所见,基本名称和描述都可以包含一些空格。我试图读入每一行并提取元素。现在,我把范围缩小到只提取基本名称。我的fscanf如下:
fscanf(file_in, "%*[^ ]s\t%128[^ ]s\t%*[^ ]s\t%[^ ]s\n", name_string, desc_string);
这并不像我希望的那样有效,而且我在缩小误差方面遇到了困难。有人知道我如何正确地阅读这些行吗?我宁愿使用
strtok
。它比fscanf更精确,因为此函数族仅在格式为100%OK时工作,否则将丢失值
看一看,我在这里更详细地解释了如何使用strtok
因此,用fgets
阅读每一行,并用strtok
解析每一行。我基本上同意Pablo的观点(即scanf
家族并不是很好的解析器),但理解如何编写scanf
模式是值得的。您正在寻找的模式如下所示:
fscanf(" %*[^\t] %128[^\t] %*[^\t] %128[^\n]", name_string, desc_string)
注:
%[xyz]
是一个指令%[xyz]s
是两个指令,第二个指令与文本s
fscanf(" %*[^\t] %128[^\t]%*[^\t] %*[^\t] %128[^\n]%*[^\n]", name_string, desc_string)
如有必要,将显式跳过字段中的其余字符。一个更好的解决方案是使用
a
修饰符并为您获得fscanf
到malloc
内存。首先,正如已经指出的那样,%[]
本身就是一个转换说明符。在[]
之后没有s
。格式字符串中的s
-es将不被视为转换说明符的一部分。你必须摆脱那些s
-es
第二,正如你自己所说,你的文件是分开的。这立即意味着您应该使用%[^\t]
转换说明符(或最后一部分的%[^\n]
说明符)提取序列的连续部分。为什么要使用%[^]
,您希望它如何工作?%[^]
实际上停止了对空格字符的解析,这与您想要的相反
在您的示例中,说明符的正确组合是
fscanf(file_in, "%*[^\t]\t%128[^\t]\t%*[^\t]\t%[^\n]\n", name_string, desc_string);
此格式字符串假定字符串的所有4部分都保证存在,并且最后一部分保证由
\n
终止。噢,哇,strtok实际上更适合于此!非常感谢。啊,我现在明白了。我对[]的用法有点困惑,但这是有道理的。虽然,我不确定使用%128[^\t]%*[^\t]读取数据比使用%128[^\t]读取数据有什么好处。@Tanaki因为如果您限制为128个字符,它将在128个字符后停止扫描,字段中的剩余字符将由下一个指令匹配,而下一个指令本应与下一个字段匹配。您是救命恩人,我忘记了溢出潜力!