【问题标题】:fscanf not converting spacesfscanf 不转换空格
【发布时间】:2021-10-28 21:45:53
【问题描述】:

我正在调试一些遗留代码。它使用 fscanf 和 [] 格式说明符来读取一些波浪号 (~) 分隔值。文件格式很简单——value~value。 value 可以是所有空格。如果第一个值全是空格,则失败。下面是一个精简的示例...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main(void)
{
        char b1[100], b2[100];


        FILE *fp = fopen( "temp_out", "r" );

        for ( int i = 0; i < 6; i++ )
        {
                int n = fscanf( fp, "%[^~]~%[^\n]\n", b1, b2 );
                printf("fscanf converted %d '%s' '%s'\n", n, n>0?b1:"",n>1?b2:"");
        }
        fclose( fp );
}

我的输入文件是……

line1~blah
     ~blah2
blah~    

这是在 RedHat 上使用 gcc 8.4.1 编译的。

如果我运行它,我会得到...

fscanf converted 2 'line1' 'blah'
fscanf converted 0 '' ''
fscanf converted 0 '' ''
fscanf converted 0 '' ''
fscanf converted 0 '' ''
fscanf converted 0 '' ''

只转换第一行。

但是,如果我交换前 2 行输入...

     ~blah2
line1~blah
blah~    

有效...

fscanf converted 2 '     ' 'blah2'
fscanf converted 2 'line1' 'blah'
fscanf converted 2 'blah' '    '
fscanf converted 0 '' ''
fscanf converted 0 '' ''
fscanf converted 0 '' ''

我可以将该行放在一个字符串中,然后 sscanf 就可以工作了。我可以使用 fgets+sscanf,这很有效,所以这是一种变通方法,但是这种模式在遗留代码中无处不在,我想知道是什么。

有什么想法吗?

【问题讨论】:

  • 请参阅What is the effect of trailing white space in a scanf() format string?,然后决定不要在格式字符串中使用尾随空格。最好通过阅读行(fgets() 或 POSIX getline())然后解析您提到的那些(sscanf())作为解决方法——这几乎可以肯定是解决问题的最佳(最简单)方法。
  • 填充数组时必须使用 field-width 修饰符,否则fscanf() 并不比gets() 更安全。如果遇到长行,您将需要"%99[^~]~%99[^\n]" 以防止写入超出数组末尾。有关缓冲区溢出问题的详细信息,请参阅:Why gets() is so dangerous it should never be used!

标签: c scanf format-specifiers


【解决方案1】:

问题在于格式中的最后一个 '\n' 字符。它匹配输入流中的任何空白字符序列。

如果您想准确地读取并忽略一个\n 字符,请使用%*1[\n] 转换。对于任何换行符序列,请使用%*[\n](这允许您跳过空行,但不能跳过完全由空格组成的行)。

更好的是,完全摆脱fscanf 并使用适当的工具解析输入。

【讨论】:

  • 谢谢。我一直忘记 fscanf 读取流,而不是逐行读取。是的,我 100% 同意你关于使用正确的解析库的观点,但与我们面临的其他问题相比,这是非常次要的。
  • %*1[\n] 的使用是可疑的。任何额外空格的变化都会导致匹配失败。如果您担心只提取一行,那么使用fgets()sscanf() 会是更好的选择。
猜你喜欢
  • 2013-02-08
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多