【问题标题】:get inputs from the file in C从 C 中的文件中获取输入
【发布时间】:2012-06-11 22:05:29
【问题描述】:

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

#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;}

【问题讨论】:

  • 这是作业吗?冒着听起来粗鲁的风险,我建议您阅读您最喜欢的 C 教科书,以了解有关指针和内存分配的更多信息......

标签: c file file-io input


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    需要注释掉的行:更改

     /*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);
    

    【讨论】:

    • 如果我错了,请纠正我,但我认为也保证可以正确读取多行。这是由于city1city2 的初始化。 malloc 调用仅使用sizeof(char*) 的大小,但发帖人可能想读取任意多行...
    • 我只是帮助避免了这个段错误的特殊原因。 OP 写的代码一团糟,无论如何都应该重新设计。
    • @H2CO3 是的,我绝不是批评您的解决方案。它确实解决了至少少数城市条目的 SEGFAULT。事实上,我对这两个答案都投了赞成票;)
    • 我也没有你的评论 :) 绝对正确。 Altgough 我懒得回答这个远远超出问题的范围。这些 malloc 转换严重伤害了我的眼睛,以至于我不能再继续看这个页面了 ;-)
    【解决方案3】:

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

    首先,请注意

    city1 = malloc(sizeof (char *));
    

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

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

    city1 = malloc(sizeof *city1 * N);
    

    我更喜欢。 *city1 的类型是 char *,所以 sizeof *city1 == sizeof (char *)。如果city1 的类型发生变化,您不必在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,因此您最终会覆盖存储在前两行中的指针,这意味着您忘记了将第一个城市名称写入的内存。然后你增加i,所以下一次循环city1[i]city2[i]不是 指向你刚刚分配的内存。

    您可能想稍微重新组织一下您的逻辑。我们现在需要跟踪两件事;我们在city1city2 中分配了多少元素,以及我们是否在输入文件的末尾。如果是我,我会这样做:

    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);
    }
    

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

    【讨论】:

      【解决方案4】:
      #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;
      }
      

      【讨论】:

        猜你喜欢
        • 2013-05-24
        • 1970-01-01
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        • 2022-01-10
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        相关资源
        最近更新 更多