【问题标题】:How to read lines with different formats如何读取不同格式的行
【发布时间】:2016-10-19 22:35:00
【问题描述】:

我有一个格式如下的输入文件

i 176064 Patterson Denise 8.58 11 DEN 15788 
q 188464
ra 148702 167443
a  73131
d 163464
f 6.00
ct 73131 PHY
b 3
p 15703
pe
m 144626 6.51 8
e

每行中的第一个字符[i,q,ra,a...] 代表一个函数的代码,而其余的是我必须存储到变量中的值,具体取决于该代码。实现这一目标的最佳方法是什么?我一直在考虑使用 fscanf 但是每一行都没有特定的格式,格式本身取决于代码 [i,q,ra,a,b..]

【问题讨论】:

  • strtok。阅读带有fgets 的行并检查每个令牌,以决定如何继续。
  • 无论做什么,都不要使用 fscanf 之类的东西。绝对是错误的工作工具。
  • 请注意,有些“代码”是多字母代码,因此它是第一个“单词”而不是“第一个字符”代表函数的代码。由于scanf() 系列函数不关心行,因此您不能使用它们来进行文件输入。您需要阅读这些行(例如fgets())然后分析它们(sscanf() 可能没问题 - 检查Using sscanf() in a loop,例如)。

标签: c string input format


【解决方案1】:

要读取,请使用fgets()

char buffer[100];
while (fgets, buffer, sizeof buffer, istream) != NULL) {

然后根据各种格式扫描该行,每个格式都以" %n" 结尾。 "%n" 记录扫描位置,如果它到达那么远。额外的测试可以检查从 n 开始的无关额外字符。

  int num1, num2, num3;
  char last[sizeof buf];
  char first[sizeof buf];
  char code[sizeof buf];
  double rate;
  int n = 0;
  //               v..v..v..v...v..v..v spaces optional here
  sscanf(buffer, "i %d %s %s %lf %d %s %d %n",
    &num1, last, first, &rate, &num2, code, &num3, &n);
  if (n) {
    Handle_i();
    continue;
  }
  sscanf(buffer, "q %d %n", &num1, &n);
  if (n) {
    Handle_q();
    continue;
  }
  sscanf(buffer, "ra %d %n", &num1, &num2, &n);
  if (n) {
    Handle_ra();
    continue;
  }
  sscanf(buffer, "e %n", &n);
  if (n) {
    Handle_e();
    continue;
  }
  ...
  fail();
}

由于每种格式都以唯一的字母模式开头,sscanf() 将在不匹配时迅速退出。

或者,代码可以解析出首字母以获得更高效的决策树。可疑的分析将显示出很小的性能差异。

与任何复杂的格式一样,请考虑如何维护代码并且它必然会发展。

【讨论】:

  • 好的,我明白了,你能再解释一下 n 整数到底是做什么的吗?
  • 好的,我明白了,你能再解释一下 n 整数到底是做什么的吗?
  • @EugG int n = 0;n 的初始值为0。sscanf(buffer, "... %n", .... &n); 将字符串buffer[] 在扫描中的那个点的扫描偏移量保存到n。如果由于之前的扫描不匹配而导致扫描从未到达"%n",则n 不会更改。
猜你喜欢
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
  • 2013-05-18
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多