Question

So I am coming from C++ for the first time with this exercise using pointers. My professor would like us to do this exercise without using index to have better mastery of pointers. I'm trying to read from a file into a 2d array embedded in a dynamically allocated struct. I hope I've worded my question well enough and provided the proper information. Thank you very much.

my struct

typedef struct  //struct that holds ASCII art
{
    char artistName[80];    //name of artist
    char asciiArt[20][80];  //actual ascii art line by line
    int rating;             //rating of art
}TextArt;

Array of struct declaration and allocation

TextArt **artPtr;
artPtr = malloc(1000 * sizeof(TextArt) + 1);

Line of code giving me problems. I read from the file fine up to this point, I'm not sure if this while is valid, I'm looking for a # in the first character. The syntax is very confusing for me here not using index, so this is where I need the most help. It is a pointer to an array of struct (*asciiArt + i) then in the struct -> a 2d c string array asciiArt[][].

        while(*tempLine != '#')   //while there is no # in position [0] -- read into temp string
        {
            printf("while templine\n");
            fgets((*asciiArt+i)->asciiArt, 100, pFile);  
        }

Full function from above code if you need more info, otherwise ignore this block of code.

void readFromFile(TextArt **asciiArt, int size, char *fileName)
{
    int index = 0; //index for array of struct
    int i = 0;
    int j = 0;
    char tempLine[500]; //temp placeholder
    FILE *pFile;


    pFile = fopen (fileName ,"r");
    if (pFile == NULL)
        printf("Error opening file");
    else
    {printf("file opened.");
        for(i = 0; pFile != NULL; i++) //*(*(data + i) + j)
        {   j=0;
            fgets((*asciiArt+i)->artistName, 100, pFile); //get artist name from first line
            printf("got artist name");

            while(*tempLine != '#')
            {printf("while templine\n");
                fgets((*asciiArt+i)->asciiArt, 100, pFile);  //while there is no # -- read into temp string
            }
            strcpy(tempLine, ""); //clear temp string
            printf("for loop done");
        }
    return;
    }
}
Was it helpful?

Solution 2

Probably

TextArt *artPtr;
artPtr = malloc(1000 * sizeof(TextArt));
...
void readFromFile(TextArt *asciiArt, int size, char *fileName){
    int index, i, ch; //index for array of struct
    char tempLine[500];
    FILE *pFile;

    pFile = fopen (fileName ,"r");
    if (pFile == NULL)
        printf("Error opening file");
    else{
        printf("file opened.");
        for(index = 0; index < size; ++index){
            TextArt *pta = asciiArt + index;
            fgets(pta->artistName, sizeof(pta->artistName), pFile);
            printf("got artist name");

            for(i=0;i<20;++i){//20 : sizeof(pta->asciiArt)/sizeof(pta->asciiArt[0])
                if(EOF==(ch=fgetc(pFile))){
                    index = size;//outer loop break
                    break;
                } else if(ch == '#'){
                    //ungetc(ch, pFile);
                    fgets(tempLine, sizeof(tempLine), pFile);
                    break;
                } else {
                    ungetc(ch, pFile);
                    fgets(pta->asciiArt + i, sizeof(pta->asciiArt[0]), pFile);
                }
            }
        }
        fclose(pFile);
    }
}

OTHER TIPS

This is a mistake:

TextArt **artPtr;
artPtr = malloc(1000 * sizeof(TextArt) + 1);

sizeof(TextArt) has nothing to do with sizeof(TextArt *). artPtr points to an array of pointers, not to an array of TextArt objects. Each of those 1000 pointers you just allocated (or tried to allocate) currently points nowhere, and you have to point each one somewhere before using them.

Update: OP clarified the intent to allocate an array of 1000 TextArts:

TextArt *artPtr;
artPtr = malloc(1000 * sizeof(TextArt));

I'm not sure what the + 1 was meant to be.

If the readFromFile function needs to possibly resize the array then you pass it like:

void readFromFile( &artPtr, ......

and inside the function you access it like:

fgets((*asciiArt)[i].artistName, 100, pFile);

Actually I'd write

TextArt *artPtr = *asciiArt;
fgets( artPtr[i].artistName, 100, pFile );

as that is easier to read instead of having brackets everywhere.

If the function does not need to reallocate then just make it take TextArt *artPtr;.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top