使用fscanf

时间:2018-09-29 02:22:32

标签: c scanf

我有这个文件:

0 -> 1:50 2:30 3:10
1 ->
2 -> 0:10 3:20
3 -> 1:20 2:10 3:30

我想使用以下代码从文件中提取所有数字:

int a, b, c;
while (fscanf(fp, "%d ->", &a) == 1) {
    printf("%d ->", a);
    while (fscanf(fp, " %d:%d", &b, &c) == 2) {
        printf(" %d:%d", b, c);
    }
    printf("\n");
}

这个想法是,在第一个循环中,它将扫描第一个数字,后跟空格,然后是->,然后内部循环将扫描以下序列“%d:%d”,直到行尾为止使外部循环返回1,因为它可以成功读取“%d->”。

代码输入:

0 -> 1:50 2:30 3:10

似乎它没有按预期工作,并且当尝试从第二行读取数字1时,外部while循环退出(但是应该吗?)。我觉得这很奇怪,因为最近我做了类似的事情,而且效果很好。

在删除循环并替换为以下代码后,我得到了正确的结果,所以它与我的循环有关:<​​/ p>

fscanf(fp, "%d ->", &a);
fscanf(fp, " %d:%d", &b, &c);
fscanf(fp, " %d:%d", &b, &c);
fscanf(fp, " %d:%d", &b, &c);
fscanf(fp, "%d ->", &a);
fscanf(fp, "%d ->", &a);
fscanf(fp, " %d:%d", &b, &c);
fscanf(fp, " %d:%d", &b, &c);
fscanf(fp, "%d ->", &a);
fscanf(fp, " %d:%d", &b, &c);
fscanf(fp, " %d:%d", &b, &c);
fscanf(fp, " %d:%d", &b, &c);

3 个答案:

答案 0 :(得分:2)

while (fscanf(fp, " %d:%d", &b, &c) == 2) {的迭代正在消耗"\n1"中的"\n1 ->"。这对以下fscanf(fp, "%d ->", &a)起犯规,该" ->"'\n'开始并终止循环。

代码需要检测" "。诸如"%d"fgets()之类的格式指令/说明符占用行尾而没有报告。


直接解决方案:由于文件是数据的,然后使用"%n"读取文本的

使用// Generous maximum line size #define LINE_N 1024 char line[LINE_N]; while (fgets(line, sizeof line, fp)) { int a; int n = 0; // v--- space needed to consume trailing whitespace sscanf(line, "%d -> %n", &a, &n) == 1) { if (n == 0) { fprintf(stderr, "Invalid line '%s'\n", line); continue; } printf("%d ->", a); char *p = line + n; while (*p) { int b,c; n = 0; // v--- space needed to consume trailing whitespace sscanf(p, "%d:%d %n", &b, &c, &n); if (n == 0) { fprintf(stderr, "Invalid rest of line '%s'\n", p); break; } printf(" %d:%d", b, c); p += n; } printf("\n"); } 记录扫描的偏移量。

   AFRAME.registerComponent('gun', {
  schema: {
    bulletTemplate: {default: '#bullet-template'},
    triggerKeyCode: {default: 32} // spacebar
  },


  init: function() {
    var that = this;
    document.body.onkeyup = function(e){
      if(e.keyCode == that.data.triggerKeyCode){
        that.shoot();
      }
    }
  },

  shoot: function() {
    this.createBullet();
  },

  createBullet: function() {
    var el = document.createElement('a-entity');
    el.setAttribute('networked', 'template:' + this.data.bulletTemplate);
    el.setAttribute('remove-in-seconds', 3);
    el.setAttribute('forward', 'speed:0.3');

    var tip = document.querySelector('#player');
    el.setAttribute('position', this.getInitialBulletPosition(tip));
    el.setAttribute('rotation', this.getInitialBulletRotation(tip));

    var scene = document.querySelector('a-scene');
    scene.appendChild(el);
  },

答案 1 :(得分:0)

该算法不处理换行符。因此它卡在第一行的末尾,无法读取与n ->匹配的任何内容。

对于所有C RTL实现可靠地起作用的一种方法是使用fgets()读取每一行(包括末尾的换行符),然后使用sscanf()来解析字符串。

答案 2 :(得分:0)

我认为您只需要在最后一个printf上查找一个字符(换行符)即可。