这么简单的代码有很多问题。
首先,请注意
city1 = malloc(sizeof (char *));
只分配一个实例 char *
,而不是一个数组char *
。您基本上已经分配city1
并city2
持有一个指向char
每个指针。如果你想city1
和city2
每个人都持有N
指向 的指针char
,那么你需要把它写成
city1 = malloc(sizeof (char *) * N);
或者
city1 = malloc(sizeof *city1 * N);
我更喜欢。的类型*city1
是char *
,所以sizeof *city1
== sizeof (char *)
。如果city1
ever 的类型发生更改,您将不必在sizeof
表达式中复制该更改。
所以:
city1 = malloc(sizeof *city1 * N);
city2 = malloc(sizeof *city2 * N);
但是,这两个数组中的元素都没有指向任何有意义的地方;您必须为每个名称分配内存,并相应地分配指针:
city1[i] = malloc(sizeof *city1[i] * 10);
既然是的类型city1[i]
,char *
那么的类型*city[i]
就是char
。
一个真正的问题是循环的结构:
city1[0] = (char*)malloc(sizeof(char)*10);
city2[0] = (char*)malloc(sizeof(char)*10);
while(fscanf(data, "%s %s %d",city1[i],city2[i], &distance)!=EOF){
city1[i] = (char*)malloc(sizeof(char)*10);
city2[i] = (char*)malloc(sizeof(char)*10);
printf("%s\n%s\n%d\n", city1[i], city2[i], distance);
i++;}
由于i
第一次通过循环时为 0,因此您最终会覆盖存储在前两行中的指针,这意味着您忘记了将第一个城市名称写入的内存。然后你 increment i
,所以下一次通过循环city1[i]
并且city2[i]
不指向你刚刚分配的内存 。
您可能想稍微重新组织一下您的逻辑。我们现在需要跟踪两件事;city1
我们在and中分配了多少元素city2
,以及我们是否在输入文件的末尾。如果是我,我会这样做:
for (i = 0; i < N; i++)
{
// first, allocate memory for the current array elements
city1[i] = malloc(...);
city2[i] = malloc(...);
// *then* read from the input file into those array elements
if (fscanf(...) != EOF)
{
printf(...);
}
else
{
break;
}
}
这将遍历输入文件,直到我们运行超过数组的末尾(for 循环的条件)或者我们在输入流中遇到 EOF(这将导致我们执行break
语句,立即退出循环)。
我认为您通过动态分配所有内容使自己的生活变得更加困难。对于第一遍,您可能只想为数组假设固定大小。您可以稍后添加更多智能。如果您知道您的城市名称长度永远不会超过 9 个字符,并且您知道您处理的城市不超过 N 个,那么只需静态声明所有内容:
char city1[N][10];
char city2[N][10];
...
while (i < N && fscanf(data, "%s %s %d\n", city1[i], city2[i], &distance) != EOF)
{
printf("%s\n%s\n%d\n", city1[i], city2[i], distance);
}
最终你会想要学习如何动态分配和扩展数组,但很明显你需要在此之前进行一些练习。走之前不需要跑。