【发布时间】:2013-05-09 08:20:41
【问题描述】:
我正在尝试解析一组格式相同的文件。这是一个示例:
NAME: br17
TYPE: ATSP
COMMENT: 17 city problem (Repetto)
DIMENSION: 17
EDGE_WEIGHT_TYPE: EXPLICIT
EDGE_WEIGHT_FORMAT: FULL_MATRIX
EDGE_WEIGHT_SECTION
9999 3 5 48 48 8 8 5 5 3 3 0 3 5 8 8
5
3 9999 3 48 48 8 8 5 5 0 0 3 0 3 8 8
5
5 3 9999 72 72 48 48 24 24 3 3 5 3 0 48 48
24
48 48 74 9999 0 6 6 12 12 48 48 48 48 74 6 6
12
48 48 74 0 9999 6 6 12 12 48 48 48 48 74 6 6
12
8 8 50 6 6 9999 0 8 8 8 8 8 8 50 0 0
8
8 8 50 6 6 0 9999 8 8 8 8 8 8 50 0 0
8
5 5 26 12 12 8 8 9999 0 5 5 5 5 26 8 8
0
5 5 26 12 12 8 8 0 9999 5 5 5 5 26 8 8
0
3 0 3 48 48 8 8 5 5 9999 0 3 0 3 8 8
5
3 0 3 48 48 8 8 5 5 0 9999 3 0 3 8 8
5
0 3 5 48 48 8 8 5 5 3 3 9999 3 5 8 8
5
3 0 3 48 48 8 8 5 5 0 0 3 9999 3 8 8
5
5 3 0 72 72 48 48 24 24 3 3 5 3 9999 48 48
24
8 8 50 6 6 0 0 8 8 8 8 8 8 50 9999 0
8
8 8 50 6 6 0 0 8 8 8 8 8 8 50 0 9999
8
5 5 26 12 12 8 8 0 0 5 5 5 5 26 8 8
9999
EOF
我想提升矩阵的维度和矩阵本身,其他的都可以丢弃。这是我目前用来尝试解析它的代码:
fp = fopen(argv[1] , "r");
for (i = 0; i < 3; ++i)
{
fscanf(fp, "\n");
}
fscanf(fp, "%d", &size);
for (i = 0; i < 3; ++i)
{
fscanf(fp, "\n");
}
cost = (double**) calloc(size, sizeof(double*));
for(i = 0 ; i < size; ++i){
cost[i] = (double*) calloc(size, sizeof(double));
}
for(i = 0 ; i < size; ++i)
{
for(j = 0 ; j < size; ++j)
{
fscanf(fp, "%lf", &(cost[i][j]));
}
cost[i][i] = 0;
}
fclose(fp);
(当我在文本编辑器中打开该文件时,它似乎有换行符 - 虽然不是在记事本中 - 我不知道为什么它们在这里消失了。名称、类型、注释、尺寸、EDGE_WEIGHT_TYPE、EDGE_WEIGHT_FORMAT 和EDGE_WEIGHT_SECTION 都出现在新行的开头。编辑:啊,谢谢,Yossarian。我是 Stack Overflow 新手!)
无论如何,我的代码不起作用。具体来说,我通过使用调试器注意到它并没有提升矩阵的维度,这意味着正确读取矩阵的尝试从一开始就注定要失败。所有变量都已声明,这不是问题。它只是不读取尺寸后的数字并将其分配给尺寸。我做错了什么?
编辑:我已经尝试过 Vicky 对 fscanf(fp, "%s\n", buf); 的建议——它还有一个优点是让我可以通过观察 buf 的值来查看它在文件中的位置——并且发现它一次只占用一个单词,而不是一条线。这种方法的问题在于 COMMENT: 行的字数不一致。使用"%*s" 和"%*s\n" 根本没有向buf 写入任何内容。
编辑 2:while((c = getchar()) != '\n' && c != 'EOF') ; 只是挂起程序。不知道它在做什么。
编辑 3:while((c = getc(fp)) != '\n' && c != 'EOF') ; 正在逐行浏览文件,但 fscanf(fp, "%d", &size); 仍然没有收到号码。
编辑 4:啊哈!得到它的工作
char c;
for (i = 0; i < 3; ++i)
{
while((c = getc(fp)) != '\n' && c != 'EOF') ;
}
fscanf(fp, "%*s");
fscanf(fp, "%i", &size);
for (i = 0; i < 4; ++i)
{
while((c = getc(fp)) != '\n' && c != 'EOF') ;
}
谢谢大家的帮助!
【问题讨论】:
-
我不认为你可以通过
fscanf(fp, "\n");来消费这样的一行,可以吗?我认为您需要fscanf(fp, "%s\n", buf);(首先适当地声明了buf)。 -
另外,C 对于这种类型的文本处理来说是一种糟糕的语言——你可以选择使用 python、perl 或其他脚本语言吗?
-
如果你想“跳过一行”,为什么不使用
int c; while((c = getchar()) != '\n&& c != EOF) ;` [让它成为一个名为“skipline”之类的函数]。 -
有点矫枉过正。
fscanf(fp, "%*s");会做得更好。 (没有任何缓冲区) -
我更愿意使用 Python - 我实际上很胜任 - 但我需要更快的 C 速度来处理我对数据进行的计算,我不知道如何去连接C和Python。感谢您的指点,将尝试两种方法!
标签: c fileparsing