我有这个文件:
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);
答案 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上查找一个字符(换行符)即可。