Thread: Structures and exception read access violation

  1. #1
    Registered User
    Join Date
    Jun 2019
    Posts
    33

    Structures and exception read access violation

    Hi i am writing some program where declare 3 stuctures code below
    Code:
    typedef struct Card
    {
        char color;
        int face;
    }CardT;
    
    
    typedef struct Player
    {
        char side;
        Card *card;
    }PlayerT;
    
    
    typedef struct Deal
    {
        Player *Gracze;
        int PointsNS;
        int PointsEW;
    }DealT;
    when i am trying to write something in stuctures i got an error type read acces violation

    Code:
    void WczytajRozdanie(DealT *Rozdanie)
    {
        char temp[3] = { '\0' };
        char linia[LINE_SIZE] = { '\0' };
        FILE *FileT = fopen("C:\\Users\\P\\Desktop\\rozdanie.txt", "r");
        if (Rozdanie == NULL)
        {
            printf("Nie mozna otworzyc pliku\n");
            return;
        }
    
    
    
    
        Rozdanie->Gracze = (PlayerT*)malloc(sizeof(PlayerT) * PLAYERS);
        while (fgets(linia, LINE_SIZE, FileT) != NULL)
        {
            for(int i=0;i<PLAYERS;i++)
            {
                
                Rozdanie->Gracze[i].card = (CardT*)malloc(sizeof(CardT) * FACE);
                Rozdanie->Gracze[i].side = linia[0]; // this works well
                for (int j = 0, len =2 ; j < FACE; j++, len += 3)
                {
                    sprintf(temp, "%2s", linia + len);
    
    
                    Rozdanie->Gracze[i].card[j].color = temp[1];//there is an error
    
    
                    if ((temp[0] >= '0')&&(temp[0] <= '9'))
                        Rozdanie->Gracze[i].card[j].face = temp[0] - '0';
                    else if (temp[0] == 'T')
                        Rozdanie->Gracze[i].card[j].face = 10;
                    else if (temp[0] == 'J')
                        Rozdanie->Gracze[i].card[j].face = 11;
                    else if (temp[0] == 'Q')
                        Rozdanie->Gracze[i].card[j].face = 12;
                    else if (temp[0] == 'K')
                        Rozdanie->Gracze[i].card[j].face = 13;
                    else if (temp[0] == 'A')
                        Rozdanie->Gracze[i].card[j].face = 14;
                }
            }
    
    
            printf("%s", linia);
            printf("\n\n");
    
    
        }
    
    
    }
    Code:
    Rozdanie->Gracze[i].card[j].color = temp[1];
    there is an error

    Can you tell me why this happend and how to fix it

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    If you want your code to be understood internationally then all of your identifiers (variable and function names, etc.) should be in English. Output text can be in Polish but it would be nice to provide translations in comments.

    If those structs compile then you are compiling as C++, not C, since you use Card and Player instead of CardT and PlayerT. To use Card and Player in C you would need to also use the struct keyword. Also, if you're compiling as C then you don't need to cast the return value of malloc.

    After trying to open the file you test Rozdanie for NULL when you should be testing FileT. (Having your file variable uppercase with a T after it makes it look like your typedef names.)

    You've forgotten to close the file.
    What you call 'color' is presumably the 'suit'.
    FACE is presumaly the number of cards in each hand.

    But you have two main problems. One is the loop structure, which needs to have the player loop on the outside with the fgets inside it.

    Secondly, sprintf (or the printf family of functions generally) does not print only 2 chars if you say "%2s". The scanf functions will only read 2 chars with that format spec, but the printf functions simply try to fit the output into a field of that size, but if the output is longer it is all printed. To limit the amount you print you'll need to put '\0's into the line string. In that case you may as well just use strtok.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define PLAYERS     4
    #define CARDS       4  // just four cards for testing
    #define LINE_SIZE 120
     
    typedef struct Card {
        char suit;
        int face;
    } CardT;
     
    typedef struct Player {
        char side;
        CardT *card;
    } PlayerT;
     
    typedef struct Deal {
        PlayerT *players;
        int PointsNS;
        int PointsEW;
    } DealT;
     
    int LoadDeal(DealT *deal) {
        char line[LINE_SIZE];
        FILE *file = fopen("rozdanie.txt", "r"); // rozdanie => deal
        if (!file) {
            printf("Nie mozna otworzyc pliku\n"); // Unable to open file
            return 1;
        }
        deal->players = malloc(sizeof(PlayerT) * PLAYERS);
        for (int i = 0; i < PLAYERS; i++) {
            if (fgets(line, LINE_SIZE, file) == NULL) {
                printf("Błąd podczas ładowania kart\n"); // Error loading cards
                return 1;
            }
            deal->players[i].card = malloc(sizeof(CardT) * CARDS);
            char *p = strtok(line, " \t\n");
            deal->players[i].side = p[0];
            for (int j = 0; j < CARDS; j++, p += 3)
            {
                if ((p = strtok(NULL, " \t\n")) == NULL) {
                    printf("Błąd podczas ładowania kart\n"); // Error loading cards
                    return 1;
                }
                CardT *c = &deal->players[i].card[j];
                c->suit = p[1];
                if (p[0] >= '0' && p[0] <= '9')
                    c->face = p[0] - '0';
                else if (p[0] == 'T')
                    c->face = 10;
                else if (p[0] == 'J')
                    c->face = 11;
                else if (p[0] == 'Q')
                    c->face = 12;
                else if (p[0] == 'K')
                    c->face = 13;
                else if (p[0] == 'A')
                    c->face = 14;
                else {
                    printf("Czarny charakter\n"); // Bad character
                    return 1;
                }
            }
        }
        fclose(file);
        return 0;
    }
     
    int main() {
        DealT deal = {NULL, 0, 0};
        if (LoadDeal(&deal)) {
            return 1;
        }
     
        for (int i = 0; i < PLAYERS; ++i) {
            PlayerT *p = &deal.players[i];
            printf("Side %c:  ", p->side);
            for (int c = 0; c < CARDS; ++c)
                printf("%d%c ", p->card[c].face, p->card[c].suit);
            printf("\n");
        }
     
        return 0;
    }
    EDIT: I just noticed that 'face' should really be 'value' or 'rank'.
    Last edited by john.c; 11-27-2021 at 08:27 PM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Error In Code - read access violation
    By rb737 in forum C Programming
    Replies: 1
    Last Post: 04-10-2018, 01:02 AM
  2. Access violation writing exception
    By arun10427 in forum C Programming
    Replies: 1
    Last Post: 04-09-2010, 12:23 PM
  3. Unhandled Exception , access violation reading locations.
    By sokoban_1 in forum C Programming
    Replies: 4
    Last Post: 04-03-2010, 05:27 AM
  4. Replies: 0
    Last Post: 04-03-2010, 02:15 AM
  5. Replies: 5
    Last Post: 07-13-2003, 01:01 PM

Tags for this Thread