【发布时间】:2014-04-09 07:07:44
【问题描述】:
我最近在必须编写的一段代码中遇到了一个有趣的问题。尽管我使用与原始方法不同的方法解决了该问题,但我想看看是否有人知道为什么原始方法不起作用。这是压缩代码sn-ps。
原文代码:
int i, j, k;
for (i=0; i!=10, (result = fgets(newline, 1024, stream))!=NULL; i++)
{
result = strtok(newline, " ");
for (j=0; j!=x; j++) {
for (k=0; k!=y; k++) {
score_matrix[i][j][k] = result;
printf("%d ", atoi(score_matrix[i][j][k]));
result = strtok(NULL, " ");
}
}
printf("\n");
}
在上面的代码中,`stream' 是一个 CSV 文件。无论如何,上面的代码会按原样打印出 CSV 文件:
19 17 20 18
9 6 10 9
12 11 10 16
3 7 9 10
0 5 8 6
15 13 15 15
20 18 18 16
17 19 19 18
13 15 14 12
10 13 18 15
但是,当我采用 与上面完全相同的代码时,但只删除了一些不相关的行:
int i, j, k;
for (i=0; i!=10; i++) {
for (j=0; j!=x; j++) {
for (k=0; k!=y; k++) {
printf("%d ", atoi(score_matrix[i][j][k]));
}
}
printf("\n");
}
打印出来:
10 13 18 15
10 0 3 8
10 13 18 15
10 0 3 18
10 0 3 18
10 13 18 15
10 13 18 15
10 13 18 15
10 13 18 15
10 13 18 15
这是非常错误的。
固定代码(只是将矩阵转换为int,并删除atoi):
int i, j, k;
for (i=0; i!=10, (result = fgets(newline, 1024, stream))!=NULL; i++)
{
result = strtok(newline, " ");
for (j=0; j!=x; j++) {
for (k=0; k!=y; k++) {
score_matrix[i][j][k] = atoi(result);
printf("%d ", score_matrix[i][j][k]);
result = strtok(NULL, " ");
}
}
printf("\n");
}
和
int i, j, k;
for (i=0; i!=10; i++) {
for (j=0; j!=x; j++) {
for (k=0; k!=y; k++) {
printf("%d ", score_matrix[i][j][k]);
}
}
printf("\n");
}
现在都打印正确的东西:
19 17 20 18
9 6 10 9
12 11 10 16
3 7 9 10
0 5 8 6
15 13 15 15
20 18 18 16
17 19 19 18
13 15 14 12
10 13 18 15
也许我在这里遗漏了一些明显的东西,但我很好奇为什么会发生这种情况。
编辑:
-
x--> 通过参数传递。在本例中为 2。 -
score_matrix--> 错误代码是char* score_matrix[10][x][y];,好的代码是int score_matrix[10][x][y]; -
newline-->char newline[1024]; -
result-->char* result; - 此外,结果已使用 printf 语句进行验证。
【问题讨论】:
-
仔细检查
score_matrix的数组边界,记住每个索引都是从零开始的。 -
score_matrix、newline和x是如何声明的? -
...
x是如何计算的? -
result = strtok(NULL, " ");是什么意思?? -
@wyas 太好了,现在阅读我的评论并理解为什么重用相同的行缓冲区并在其中存储偏移量(这都是
strotok所做的;在提供的缓冲区中返回终止的子字符串)是 错误。这些行似乎报告的数据与 last 行相同,这绝非巧合。如果您仍然需要int的数据,只需使用“固定”版本并避免只能通过动态分配(以及以后的动态清理)解决的问题。
标签: c