【问题标题】:Values in index are replaced every iteration每次迭代都会替换索引中的值
【发布时间】:2013-06-30 04:23:39
【问题描述】:

我创建了一个 C 程序,我应该在其中读取一个文本文件并通过 int 和 string 指针将其分配给一个结构。

这是我的程序的代码 sn-p:

i = 0;
while(!feof(phoneBook)) {
    fscanf(phoneBook, "%d|%s\n", &num, fname);
    info[i].phone_num = num;
    printf("%d\n", info[i].phone_num);
    info[i].first_name = fname;
    printf("%s\n", info[i].first_name);

    i++;
    ctr++; 
    printf("\nfirst:%s", info[0].first_name); 
    printf("\nsecond:%s", info[1].first_name);
    printf("\nthird:%s\n\n", info[2].first_name);       
}

在第一次迭代中,它将第一行分配给 info 的 0 索引。 对于第二次迭代,它将第二行分配给索引 1 并替换索引 0。

文本文件仅包含以下几行(用于测试目的): 第一的 第二 第三个

这是输出:

//first iteration
first:first
second: <null>
third: <null>
//second
first:second
second: second
third: <null>
//third
first:third
second: third
third: third

顺便说一句,我将我的结构声明为:

typedef struct{
    int id;
    char *first_name;
    char *last_name;
    int phone_num;
} phone_det;

其中 phoneBook 在数据类型 phone_det 下声明。

我们将不胜感激任何形式的帮助!我刚开始使用 C,但我仍然对指针感到有些困惑。 :(

【问题讨论】:

  • 你的信息结构是什么样的?它是如何声明的?
  • 不要这样使用feof();它给了你错误的答案。更具体地说,您必须检查来自fscanf() 的值,因为它会在feof() 之前告诉您有关EOF 的信息。
  • 更新你的问题;不要将结构添加为注释。
  • 谢谢大家!终于实现了整个指针字符串数组的事情。现在没事了。非常感谢!!!!!! :)

标签: c arrays pointers scanf


【解决方案1】:

虽然我们看不到你的结构,但你每次将指针分配给相同的名称缓冲区,并且不将名称缓冲区本身复制到特定的数组,所以你最终有许多指向同名缓冲区的不同指针。

【讨论】:

    【解决方案2】:

    问题是分配info[i].first_name = fname;。这不会复制字符串 - 它只是将info[i].first_name 设置为指向fname 指向的同一内存。所以每次迭代之后,它们都指向fname指向的同一个内存。因此,当您fscanf 一个新值进入缓冲区时,所有结构都会看到新内容。

    【讨论】:

    • 所有答案都指出了同一个问题,但这个问题在我看来最清楚/最简洁!
    【解决方案3】:

    您分配info[i].first_name 指向fname; 而不是将fname 声明为:char* fname;(正如我假设您所做的那样),执行以下操作:char[MAX_SIZE] fname;,然后使用strcpy 来复制该值。这样做:strcpy(info[i].first_name, fname);

    【讨论】:

      【解决方案4】:

      这是一个猜测,因为我看不到您的所有代码,但我敢打赌,这些项目只有 char *,也就是说,您正在将指针分配给字符串。

      fname 实际上是一个缓冲区。 (可能是一个字符 fname[20]),所以每个项目都指向 fname,每次读取都会发生变化。

      要解决这个问题,让结构包含一个数组。然后使用strcpystrncpy 从fname 复制。

      【讨论】:

        【解决方案5】:

        您应该复制名称,而不是指向它。您正在将所有指针设置为您将姓氏读入的位置。使用strcpy 或类似的。

        或者,为了让生活更简单,确保为 first_name 元素分配了足够的空间,然后直接使用

        fscanf(phoneBook, "%d|%s\n", &(info[i].phone_num), info[i].first_name);
        

        【讨论】:

          【解决方案6】:

          每次迭代都读入fname,然后将fname的地址分配给info[i].first_namefname 的地址在每次迭代之间都不会改变,因此您将相同的地址分配给所有 first_name 指针!

          您需要为每次迭代分配一个唯一的数组,以便将字符串存储在不同的位置,而不是每个都覆盖最后一个。

          while(!feof(phoneBook)) {
              char *fname = malloc(SUITABLY_LARGE_SIZE);
          
              if (fname == NULL) {
                  perror("malloc");
                  exit(1);
              }
          
              fscanf(phoneBook, "%d|%s\n", &num, fname);
              info[i].first_name = fname;
          
              ...
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-10-08
            • 2020-08-27
            • 2020-07-15
            • 1970-01-01
            • 2011-10-11
            • 2011-08-16
            • 2012-12-23
            • 1970-01-01
            相关资源
            最近更新 更多