views:

91

answers:

4

I am attempting to read a file with some random names in the format "ADAM","MARK","JESSIE" .....

I have some constraints, the file should be read in a function but should be accessible form the main function with no global variables. The file size and the no of names in the file are not known. This is what I have done till now. I have some difficulty with dynamic 2d array as I have not used them much.

/* 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;
}

I use WxDev and am getting an error "invalid type argument of `unary *' when I try to assign the null character.

Any pointers on how to do this?

A: 

is this about the TU assignment?

peter
-1 should not be an answer; at best this could be a comment
pmg
+1  A: 

Take a closer look at this expression from the line generating the error and think about what it's doing:

**name_array[pos][j]

Remembering that brackets have higher precedence than unary *, this is equivalent to *(*((name_array[pos])[j])), which is 2 subscripts followed by 2 dereferences. That's a total of 4 dereferences, since foo[i] is equivalent to *(foo+i). The declared type of name_array is char **, which means you can only dereference it twice. Think of the type declaration char **name_array as meaning that **name_array has type char, since that's the basis for type declaration syntax (see the History of C, "Embryonic C").

Off topic

Another issue arises on the line:

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

Here, you're only allocating enough space for a single character in each element of name_array.

outis
@outis: Thanks for pointing out the mistake in the deferences and the memory allocation. I will do more reading on the topic.
Gan
A: 
            **name_array[pos][j]='\0'; \\error here

I see that name_array is declared as

char **name_array

Problem is that

**name_array[pos][j] tries to dereference (twice!!) a character

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

You cannot dereference a character.

Suggestion: simplify your code.
When code doesn't "behave", it usually is not because it is too simple ;)

pmg
@pmg: Thanks for the explanation. I will do more reading on this topic.
Gan
A: 

This might seem pedantic, but it is important. You aren't using a 2D array. In fact, you don't create ANY arrays in your code.

One of the important things to understand is that arrays "decay" into pointers.

link text

Much of the confusion surrounding arrays and pointers in C can be traced to a misunderstanding of this statement. Saying that arrays and pointers are 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'spointer arithmetic and array indexing [that] are equivalent in C, pointers and arrays are different.'')

rox0r