C fgets() - В массив записывается только последняя строка файла?

У меня действительно странная проблема с fgets() в C. Ниже приведен код, с которым я работаю.

FILE* conf_file;
char array[20];
conf_file=fopen("configuration","r");
if (!conf_file) printf("There is not conf file");
while(!feof(conf_file)){
    // if( feof(conf_file)) break;
    fgets(array,20,conf_file);
    //printf("%s",array);
    if (!read_id_flag){
        labris_id=atoi(array);
        read_id_flag=1;
        printf("%d\n",id);
        continue;
    }
    protocol_array[protocol_index]=array;
    // printf("%s %s",array,protocol_array[protocol_index]);
    protocol_index++;
}
int i;
for(i=0;i<10;i++){
    printf("%s",protocol_array[i]);
}
fclose(conf_file);

Что ж, в области while, если я попытаюсь напечатать protocol_array, все работает отлично. Но если я попытаюсь напечатать массив после области while, он напечатает только последнюю строку массива, 6 раз (6 — количество строк в файле).

Любая идея приветствуется. Заранее спасибо.


person 0xmtn    schedule 05.03.2012    source источник
comment
char array[20]; protocol_array[protocol_index]=array; вот в чем проблема.   -  person Karoly Horvath    schedule 05.03.2012
comment
Я думал, что сделал. Простите за это. Какой-то парень сделал отступ для меня. ;)   -  person 0xmtn    schedule 05.03.2012
comment
@KarolyHorvath Что с этим не так? Я имею в виду, что это статический массив, и внутри области while массив получает строку за раз, и я могу поместить ее в protocol_array. Но ниже области это не работает.   -  person 0xmtn    schedule 05.03.2012
comment
Покажите определение protocol_array. Скорее всего, вы назначаете указатель на один и тот же array шесть раз. Вот почему вы получаете один и тот же контент после цикла — все ваши элементы в protocol_array указывают на один и тот же array!   -  person Alex    schedule 05.03.2012
comment
protocol_array объявление: char* protocol_array[];   -  person 0xmtn    schedule 05.03.2012
comment
Если protocol_array равно char * protocol_array[], то вы можете рассмотреть protocol_array[protocol_index]=strdup(array); или некоторую комбинацию семейства malloc + семейство strcpy с завершением \0 для каждого массива символов (поскольку вы рассматриваете его как строку C). Не забудьте free их, когда закончите.   -  person another.anon.coward    schedule 05.03.2012


Ответы (2)


char* protocol_array[]; не может содержать никаких данных напрямую, кроме указателя на выделенную память.

Вы должны либо определить protocol_array как char protocol_array[20][6];, выделив хранилище для 6 строк строки длиной 20 и strcpy следующим образом:

char protocol_array[20][6];
//...
strcpy( protocol_array[protocol_index], array );

или выделить память через malloc:

char** protocol_array = malloc( 6 * sizeof( char* ) );
//...
protocol_array[protocol_index] = malloc( strlen(array)+1 );
strcpy( protocol_array[protocol_index], array );

Обратите внимание, что в последнем случае вы должны free выделенную память, когда закончите с ней:

for( i = 0; i<protocol_index; ++i )
    free( protocol_array[i] );
free( protocol_array );
person Alex    schedule 05.03.2012

protocol_array[protocol_index]=массив; - Эта линия, кажется, проблема. Вы должны сделать strcpy.

Если вы продолжаете назначать массив каждый раз, только адрес массива (который является локальным массивом) сохраняется во всех элементах protocol_array. Как видно из вашего кода, последняя прочитанная строка будет присутствовать в «массиве», и, поскольку все элементы protocol_array указывают на адрес «массива», он просто печатает это для всех элементов.

person Jay    schedule 05.03.2012
comment
Но если вы собираетесь выполнять strcpy, вам также следует выделить немного памяти для каждого элемента protocol_array. Если ваш массив протоколов char *protocol_array[], то для каждого элемента требуется выделение памяти. Будьте осторожны с этим. - person Jay; 05.03.2012