2D массив с использованием указателей - PullRequest
0 голосов
/ 12 октября 2010

Я пытаюсь прочитать файл с некоторыми случайными именами в формате "ADAM", "MARK", "JESSIE" .....

У меня есть некоторые ограничения, файл должен читаться в функции, но должен быть доступен из основной функции без глобальных переменных. Размер файла и количество имен в файле не известны. Это то, что я сделал до сих пор. У меня возникли некоторые трудности с динамическим 2d-массивом, так как я не использовал их много.

/* Function to read from the file */
int read_names(FILE *input, char ***names, int *name_count)
{
    int f1,size,count,i,j=0;
    char **name_array,*text,pos=0;
    /* get the file size */
    f1=open("names.txt",O_RDONLY);
    size=lseek(f1,0,SEEK_END);
    close(f1);
    /* Reading all the characters of the file into memory */
    //Since file size is known we can use block transfer
    text=(char *) malloc(size * sizeof(char) );
    fscanf(input,"%s",text);

    /* Finding the no of names in the file */
    for(i=0;i<size;i++)
    {
        if(text[i]==',')
            count++;
    }
    printf("No. of names determined\n");

    /* Assigning the Name count to the pointer */
    name_count=(int*)malloc(sizeof(int));
    *name_count=count;


    name_array=(char **) malloc(count * sizeof(char *));
    for(i=0;i<count;i++)
    {
        name_array[i]=(char*) malloc(10 *sizeof(char ));
    }
    for(i=0;i<size;i++)
    {
        if(text[i]!='"')
            if(text[i]==',')
            {
                **name_array[pos][j]='\0'; //error here
                pos++;
                j=0;
            }
            else
                name_array[pos][j++]=text[i];
    }
    printf("Names Counted\n");
    printf("Total no of names: %d\n",*name_count);
    names=(char ***) malloc(sizeof(char **);
    names=&name_array;
    return 1;
}

/* Main Function */
int main(int argc, char *argv[])
{
    FILE *fp;
    char ***names;
    int *name_count;
    int status;
    // Opening the file
    fp = fopen("names.txt","r");
    // Now read from file
    status = read_names(fp,names,name_count);
    printf("From Main\n");
    fclose(fp);
    system("PAUSE");
    return 0;
}

Я использую WxDev и получаю сообщение об ошибке «Недопустимый аргумент типа« унарный * »при попытке присвоить нулевой символ.

Есть какие-нибудь указатели о том, как это сделать?

Ответы [ 3 ]

1 голос
/ 12 октября 2010

. Внимательно посмотрите на это выражение из строки, генерирующей ошибку, и подумайте, что она делает:

**name_array[pos][j]

Помня, что скобки имеют более высокий приоритет , чем унарный *, это эквивалентно *(*((name_array[pos])[j])), то есть 2 подписки, за которыми следуют 2 разыменования. Это всего 4 разыменования, поскольку foo[i] эквивалентно *(foo+i). Объявленный тип name_array равен char **, что означает, что вы можете разыменовать его только дважды. Представьте, что объявление типа char **name_array означает, что **name_array имеет тип char, поскольку это основа для синтаксиса объявления типа (см. История C , «Зародыш C»).

Не по теме

Другая проблема возникает на линии:

name_array[i]=(char*) malloc(sizeof(char ));

Здесь вы выделяете достаточно места только для одного символа в каждом элементе name_array.

0 голосов
/ 12 октября 2010

Это может показаться педантичным, но это важно. Вы не используете 2D-массив. На самом деле, вы не создаете ANY массивов в своем коде.

Одна из важных вещей, которую нужно понять, состоит в том, что массивы "распадаются" на указатели.

текст ссылки

Большая часть путаницы вокруг массивов и указателей в C может быть связана с неправильным пониманием этого утверждения. Сказать, что массивы и указатели equivalent'' means neither that they are identical nor even interchangeable. What it means is that array and pointer arithmetic is defined such that a pointer can be conveniently used to access an array or to simulate an array. In other words, as Wayne Throop has put it, it's арифметика указателей и индексация массивов [которые] эквивалентны в C, указатели и массивы различны.

0 голосов
/ 12 октября 2010
            **name_array[pos][j]='\0'; \\error here

Я вижу, что name_array объявлен как

char **name_array

Проблема в том, что

**name_array[pos][j] пытается разыменовать (дважды !!) символ

**   (name_array[pos]) [j];    /* name_array[pos] is of type (char*) */
** ( (name_array[pos]) [j] );  /* name_array[pos][j] is of type (char) */

Вы не можете разыменовать символ.

Предложение: упростите ваш код.
Когда код не "ведет себя", обычно это не так, потому что он слишком прост ;)

...