fscanf和换行符

16

我使用fscanf从配置文件中读取设置行。 这些设置具有严格预定义的格式,看起来像:

name1=option1;
name2=option2;
...

基本上,我这么做。

fscanf(configuration,"%[^=]=%[^;];",name,option);

其中 configuration 是文件流,name 和 option 是程序缓冲区。

问题在于 name 缓冲区包含了一个我不想要的换行符。是否有格式说明符在“[^...]”集中我错过了跳过换行符?无论如何,它能通过格式说明符解决吗?

顺便说一下:通过编写此内容吞咽换行符

"%[^=]=%[^;];\n"

我认为这不够优美,因为换行符可能会在任何地方重复多次。


1
如果 nameN 字段不能包含空格,只需在格式字符串的前面添加一个空格 - " %[^=]=%[^;];" - 以跳过前导空格。如果它们可以包含空格,则需要使用 getchar() 单独消耗换行符。 - Daniel Fischer
1
接受的答案是正确的,无论如何,关于重复的换行符,您可以使用%* [\n]来读取任意数量的'\n'而不存储它们。 - effeffe
3个回答

15

只需在格式字符串末尾添加空格:

"%[^=]=%[^;]; "

这将会吃掉所有的空白字符,包括换行符。

引用自cplusplus.com

空白字符:在下一个非空白字符之前遇到的任何空白字符都将被读入并忽略(空白字符包括空格、换行和制表符 -- 参见 isspace)。在格式字符串中出现一个空白字符就可以匹配从流中提取的任意数量的空白字符(包括没有空白字符)。


8
另一种方法是使用fgets()将整行读入字符串,然后使用sscanf()。这样做的优点在于调试时可以清楚地看到函数正在处理哪些数据。

1
这将起作用:
fscanf(configuration,"%[^=]=%[^;];%[^\n]",name,option,dummy);
您必须消耗换行符。否则,换行符会留在输入流中。

哦,那么虚拟变量应该有多大呢?足够大以吞噬所有可能的换行符吗? - Yang
既然您说您有严格预定义的输入数据格式,那么您可以计算出所需的确切字符数量并创建虚拟变量。这将帮助您发现任何可能偏离输入格式的情况,而不是跳过它们(这将在使用fscanf或fgets中的空格之前或之后发生)。 - askmish
1
末尾缺少一个“%”,为什么不使用“%[^=] = %[^;];%* [^\n]”并忘记那些换行符和包含它们的缓冲区呢? - effeffe
@effeffe:这也是个好主意。OP的问题说明输入字符串格式将是固定的,因此我采用了这种方法,认为它可能有助于找出文件中是否有任何行不符合固定格式的标准。 :) - askmish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接