-3

大家好,我尝试将所有城市名称保存在一个数组中,但我无法得到结果,我该怎么做?

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
char**city1,** city2;
int distance,i=0;

city1 = (char**) malloc(sizeof(char*));
city2 = (char**) malloc(sizeof(char*));
    FILE* data;
data = fopen(argv[1],"r");
     //fscanf(data, "%s %s %d", city1,city2, &distance);

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++;}
fclose(data);
return 0;}
4

4 回答 4

1

你需要第二对 malloc 之前fscanf()。您正在将输入写入内存的随机部分。

于 2012-06-07T19:50:04.317 回答
1

您已注释掉的行是需要的:更改

 /*city1[0] = (char*)malloc(sizeof(char)*10);
city2[0] = (char*)malloc(sizeof(char)*10);*/

至:

city1[0] = (char*)malloc(sizeof(char)*10);
city2[0] = (char*)malloc(sizeof(char)*10);

因为没有它, char * 指针将指向任意(无效)位置。

顺便说一句,作为旁注,这是不好的做法 1. 强制转换malloc(), 2. 的返回值。使用sizeof(type)而不是sizeof(*variable). 所以你最好把你的代码改成

city1[0] = malloc(sizeof(city[0][0]) * 10);
city2[0] = malloc(sizeof(city[0][0]) * 10);
于 2012-06-07T19:51:45.533 回答
0
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(int argc, char* argv[]){
    char **city1, **city2;
    int distance,i=0;

    city1 = (char**) malloc(sizeof(char*));
    city2 = (char**) malloc(sizeof(char*));
    FILE* data;
    data = fopen(argv[1],"r");
     //fscanf(data, "%s %s %d", city1,city2, &distance);

    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){
        printf("%s\n%s\n%d\n", city1[i], city2[i], distance);
        ++i;
        city1 = (char**)realloc(city1, (i+1)*sizeof(char*));
        city2 = (char**)realloc(city2, (i+1)*sizeof(char*));
        city1[i] = (char*)malloc(sizeof(char)*10);
        city2[i] = (char*)malloc(sizeof(char)*10);
    }
    fclose(data);
    {//check & free
        int j;
        for(j=0;j<i;++j){
            printf("%s\t%s\n", city1[j],city2[j]);
            free(city1[j]);free(city2[j]);
        }
        free(city1[j]);free(city2[j]);//OK?
        free(city1);free(city2);
    }
    return 0;
}
于 2012-06-07T22:00:10.910 回答
0

这么简单的代码有很多问题。

首先,请注意

city1 = malloc(sizeof (char *));

只分配一个实例 char *,而不是一个数组char *。您基本上已经分配city1city2持有一个指向char每个指针。如果你想city1city2每个人都持有N指向 的指针char,那么你需要把它写成

city1 = malloc(sizeof (char *) * N);

或者

city1 = malloc(sizeof *city1 * N);

我更喜欢。的类型*city1char *,所以sizeof *city1== sizeof (char *)。如果city1ever 的类型发生更改,您将不必在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);
}

最终你想要学习如何动态分配和扩展数组,但很明显你需要在此之前进行一些练习。走之前不需要跑。

于 2012-06-07T21:16:15.163 回答