1

I am trying to access all values that I call. I'm not sure if I use array values correctly. In code below I'm trying to write values in file to memory and then call them by address. what is the problem? Am I overwriting on same memory adresses or I call them wrongly? Any help please?

my text file:

0 0 100 500 player1

0 1 400 450 player2

1 1 300 600 player3

FILE *fp;
struct ob {
  int x;
  int y;
  int c_hp;
  int max_hp;
  char name[100];
  int p_id;
};

struct ob *ptr;
int count = 0;
int main(int argc, char *argv[]) {
  if (argc != 2) {
    printf("Usage: program <File name>\n");
    exit(1);
  }
  read_player_values();
}

void read_player_values() {
  ptr = (struct ob *)malloc(sizeof(struct ob));

  if (ptr == NULL)
    printf("out of memory");
  else {
    while (!feof(fp)) {
      count++;
      fscanf(fp, "%d%d%d%d%s", &ptr->x, &ptr->y, &ptr->c_hp, &ptr->max_hp,
             ptr->name, &ptr->p_id);
      ptr->p_id = count;
      printf("%d %d %d %d %s %d", ptr->x, ptr->y, ptr->c_hp, ptr->max_hp,
             ptr->name, ptr->p_id);
      printf("\n");
    }
    fclose(fp);

    printf("------\n");
    for (int i = 0; i < count; i++) {
      /* here is my problem */
      /*trying to print all player names here*/
      printf("%s\n", (ptr - i)->name);
    }
  }
}
Community
  • 1
  • 1
hhilal
  • 163
  • 2
  • 4
  • 17
  • 1
    Where do you assign `fp`? In `main` you check whether filename was passed, but don't use it. – fas Apr 14 '20 at 11:29
  • `ptr` is not a pointer to an `ob` array but a pointer to a single `ob` struct, but you seem to assume that its an array with the printing part. You just rewriting this single `ob` element with every loop iteration and not building an array as you might want. – Eraklon Apr 14 '20 at 11:33
  • I'm calling `read_player_values()` method after that and assing `fp` in `fscanf` . I'm reading file values and assing them to struct variables – hhilal Apr 14 '20 at 11:35
  • @Eraklon how can build an array to contain all my file values? – hhilal Apr 14 '20 at 11:37
  • The point is that you need to call `fopen` somewhere. – Lundin Apr 14 '20 at 11:39
  • 1
    after `count++` you can do something like `ptr = realloc(ptr, count * sizeof(struct ob));` and use `ptr` like `&ptr[count-1].x` in every place. – Eraklon Apr 14 '20 at 11:40
  • https://stackoverflow.com/q/5431941/6699433 – klutt Apr 14 '20 at 11:51
  • And what is the actual problem here? Please provide a [mre] – klutt Apr 14 '20 at 11:55

1 Answers1

1

Firstly, you have to open the file in main function:

fp = fopen(argv[1],"r");
if (!fp)
   return -1;

You can use fgets function to get each line of the file and get all values from this line by using sscanf. After each iteration, you have to re-allocate for ptr. ptr here likes an array that has count elements.

char line_buf[256];
count = 1;
while (fgets(line_buf, sizeof(line_buf), fp)) {
      ptr = realloc(ptr, count * sizeof(struct ob));
      if(!ptr)
         return;
      sscanf(line_buf, "%d%d%d%d%s\n", &ptr[count-1].x, &ptr[count-1].y, &ptr[count-1].c_hp, &ptr[count-1].max_hp,
             ptr[count-1].name);
      ptr[count-1].p_id = count;
      printf("%d %d %d %d %s %d", ptr[count-1].x, ptr[count-1].y, ptr[count-1].c_hp, ptr[count-1].max_hp,
             ptr[count-1].name, ptr[count-1].p_id);
      printf("\n");
      count++; 
}

For printing all names:

    printf("------\n");
    for (int i = 0; i < count-1; i++) {
      printf("%s\n", ptr[i].name);
    }

the result after testing:

#cat text.txt
0 0 100 500 player1
0 1 400 450 player2
1 1 300 600 player3

./test text.txt
0 0 100 500 player1 1
0 1 400 450 player2 2
1 1 300 600 player3 3
------
player1
player2
player3

Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • 1
    The small problem with the order of realloc is that you will have one extra element in the array when the loop exits. – Eraklon Apr 14 '20 at 12:46
  • I got it, so we can reallocate before increasing the count value. I will update it as soon as possible and use ptr[count-1], init count = 1. Thanks – Hitokiri Apr 14 '20 at 12:52