2013-06-30 4 views
1

Я создал программу на 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);  
} 

На первой итерации, он присваивает первую строку в 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 был объявлен под типом datatype phone_det.

Любая форма помощи будет принята с благодарностью! Я только начал использовать C, и я все еще немного запутался с указателями. :(

+2

Как выглядит ваша структура информации? И как это объявлено? –

+1

Не используйте 'feof()' like this; это дает вам неправильный ответ. В частности, вы должны проверить значение из 'fscanf()', потому что он расскажет вам об EOF до 'feof()' can. –

+1

Обновите свой вопрос; не добавляйте структуру в качестве комментария. –

ответ

2

Хотя мы не можем видеть вашу структуру, вы присваиваете указатель одному и тому же имени буфера каждый раз и не копируете сам буфер имен в конкретный массив, поэтому вы получаете множество разные указатели на одноименный буфер.

0

Это предположение, потому что я не вижу весь ваш код, но я уверен, у вас есть только char * для этих элементов, то есть вы назначаете указатели на строку.

fname На самом деле это буфер. (Возможно, char fname [20]), поэтому каждый элемент указывает на fname, который изменяется при каждом чтении.

Чтобы устранить эту проблему, создайте структуру, содержащую массив. Затем используйте strcpy или strncpy, чтобы скопировать его из fname.

1

Проблема связана с заданием info[i].first_name = fname;. Это не делает копию строки - она ​​просто устанавливает info[i].first_name, чтобы указать на ту же память, на которую указывает fname. Поэтому после каждой итерации все они указывают на ту же память, на которую указывает fname. Таким образом, когда вы добавили новое значение в буфер, все структуры видят новое содержимое.

+0

Все ответы определяют ту же проблему, но это говорит об этом наиболее четко/кратко в моем сознании! – Floris

0

Вам следует скопировать имя, а не указывать на него. Вы устанавливаете весь указатель на место, в которое вы ввели последнюю фамилию. Используйте strcpy или некоторые из них.

Или, чтобы сделать жизнь еще проще, убедитесь, что first_name элемент был назначен достаточно места, а затем прочитать непосредственно в него с

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

Каждая итерация читает в fname, а затем назначить адрес'S fname «s в info[i].first_name. Адрес fname не меняется между каждой итерацией, поэтому вы назначаете один и тот же адрес всем указателям 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; 

    ... 
} 
1

Ваше назначение info[i].first_name, чтобы указать на fname; Вместо того, чтобы объявить fname как: char* fname; (как я предполагаю, что вы сделали), сделать что-то вроде этого: char[MAX_SIZE] fname;, а затем использовать strcpy скопировать значения. Так делают: strcpy(info[i].first_name, fname);

Смежные вопросы