每次迭代都会替换索引中的值

时间:2013-06-30 04:23:40

标签: c arrays pointers scanf

我创建了一个C程序,我应该读取一个文本文件并通过int和字符串指针将它分配给一个结构。

这是我程序的代码片段:

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,我仍然可以对指针感到困惑。 :(

6 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

这是一个猜测,因为我看不到你的所有代码,但我敢打赌,你只需要为这些项目设置char *,就是你将指针分配给一个字符串。

fname实际上是一个缓冲区。 (也许是一个char fname [20])所以每个项目都指向fname,每次读取都会随之改变。

要解决此问题,请使结构包含数组。然后使用strcpystrncpy从fname复制它。

答案 4 :(得分:0)

您应该复制名称,而不是指向它。您将所有指针设置为您读取姓氏的位置。使用strcpy或其他一些。

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

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

答案 5 :(得分:0)

每次迭代都会读入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;

    ...
}