【问题标题】:fscanf - how to process two floats + whitespace + newline?fscanf - 如何处理两个浮点数+空格+换行符?
【发布时间】:2012-11-04 19:53:30
【问题描述】:

使用 fscanf 我想处理包含两个浮点数的文本,浮点数之前、之间或之后的任意数量的空格(包括换行符/返回),以及最后的换行符。如果多于/少于两个数字,那么我想检测并报告错误。

这似乎适用于处理空白,但它不会检测是否存在两个以上的浮点数:

fscanf(f, "%f %f", &sx, &sy);

这似乎也同样有效:

fscanf(f, "%f %f%*[ \n\t\r\f\v]\n", &sx, &sy);

有没有更好的方法来处理这个问题?

【问题讨论】:

  • 您的最后一个示例如何捕获最后一个换行符?它不是通过正则表达式得到的吗?
  • @effeffe:好点,我想确保最后确实有一个换行符,否则无法保证正则表达式找到换行符,但我不确定这是正确的方法。
  • 好吧,scanf 总是会失败,没有字符串可以匹配%[a]a 格式
  • @David:你现在所说的空白到底是什么意思?换行符对你来说算不算空格?
  • @askmish:在标准 C 中,换行符是空格,他将换行符放在他的正则表达式和他的问题中,所以......是的。来自 OP:"...(包括换行符/回车符),最后是换行符。"

标签: c stdio scanf


【解决方案1】:
fscanf(f, "%f%f", &one, &two);
while (1) {
  ch = fgetc(f);
  if (ch == EOF) /* end of input whithout a line break */break;
  if (ch == '\n') /* input ok */break;
  if (!isspace((unsigned char)ch)) /* bad input */break;
}

【讨论】:

  • :你的意思是使用 fscanf 还是 scanf?
  • 这似乎可行,我希望有一种方法只使用 fscanf 但可能没有。
  • 如何处理最后的多个尾随换行符?而且我不认为演员是必要的
  • @askmish:我的错:我只是复制粘贴了原始代码,没有注意。这是fscanf(),我在参数中缺少一个流。
  • @effeffe:在未定义行为的惩罚下需要强制转换。查看C99C11 Standard 中的7.4/1。
【解决方案2】:

我不知道如何使用单个 *scanf 来做到这一点,由于您的请求的最后一部分,我认为这是不可能的,*scanf 无法读取与简单正则表达式匹配的任意长度的字符序列 并以指定字符结尾。

int character;
bool trailingNewLine;

if (fscanf(f, "%f%f", &sx, &sy) < 2)
    // not matching "whitespace-float-whitespace-float"
    // being more accurate could be painful...

// read arbitrary quantity of white space ending with '\n'
while (isspace(character = getc(f)))
    trailingNewLine = (character == '\n');

// the last one wasn't white space, doesn't belong to this one
ungetc(character, f);

if (!trailingNewLine)
    // missing newline at the end

// OK!

【讨论】:

  • 只有当中间的任意空格不包含换行符时,您的解决方案才会起作用。 :) isspace() 也会检查换行符。
  • 你说的是两个浮点数之间的空白吗? C11 标准规定这是转换规范的第一步:“跳过输入的空白​​字符(由 isspace 函数指定),除非规范包含 [、c 或 n 说明符。)” 所以在阅读第二个浮点数之前应该阅读并丢弃中间的换行符......我误解了这个还是你的评论?
  • 我说的是第二个浮点数和行尾换行符之间的空格。 1.2 2.3 \n\n\n\n\n\n\n\n(I am talking about this space)\n\n
  • fscanf() 调用返回 1 也是错误。事实上,除了 2 之外的任何内容都是错误,对吧?
【解决方案3】:

如果您具体了解必须读入多少个字符(或知道一行中的最大字符数),请使用:
fread ( stringbuffer, size, count,Filepointer );

然后使用: sscanf() 读取两个浮点数,然后使用 for 循环计算编号。读取字符串中的空格数。

您也可以使用strtok()

注意:读取输入流直到行尾(在您的情况下,行尾由新行标记)包括中间的空格(因为在 C 中,至少,空格也包含新行) 太模糊了。在这种情况下,最好使用 fread 分块读取数据并处理存储的数据,直到到达特定的行尾。

【讨论】:

  • 如果您想使用 isspace(),请检查它是否也是换行符,以及它是否也符合您的规范。
【解决方案4】:
scanf("%f %f%*c", &sx, &sy);
// %*c will read and discard all eventual characters after the second float

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多