0

I want to write a couple of strings (names) into a pointer array. I have written a code that I think logically would do this, but for some reason, it only prints the last string. What could be the solution for this?

#include <stdio.h>
#include <stdlib.h>
#define MAX 50

int jatekosell(char* s) {

    int n, ok = 1;

    n = atoi(s);

    if(n<3 || n > 15) 
    {
        printf("Nem jo! 3 es 15 koze kell essen!");
        getline(s, MAX);
        ok = 0;
    }
    return ok;

}

int getline(char *s, int n);

void main() {

    char amount[MAX];
    char name[MAX];
    char *names[MAX];
    int number, i, j;
    printf("Number of players between 3 and 15: ");
    getline(amount, MAX);   
    while(!jatekosell(amount));
    number = atoi(amount);

    for(i = 0; i < number; i++)
    {
        printf("Type the %d. name: ", i+1);
        getline(name, MAX);
        names[i] = name;



    }

    for(i = 0; i < number; i++)
    {
        printf("The names: %s\n", names[i]);

    }




    getchar();

}

int getline(char *s, int n){ 
    int c; 
    char *t=s;
    while(n-- > 0 && (c=getchar())!=EOF&&c!='\n') *t++ = c;
    *t='\0';
    while(c!=EOF&&c!='\n') c=getchar();
    return(t-s); 
}

3 Answers3

0

You are storing the same memory position (the name variable) into each of the names array items. You can see that by changing %s to %p when printing (to show the memory address of name[i]).

Instead of just assigning names[i] = name, you'll need to copy the contents of name into names[i].

Lauro Moura
  • 750
  • 5
  • 15
0

You've declared a single buffer to getline() your data into, char name[MAX];.

You read data in there, then "put it into your array" with names[i] = name;.

The problem is every element in your array points to the same single buffer and each successive getline() just overwrites the contents of that buffer.

You could solve this by replacing names[i] = name; with names[i] = strdup(name); The strdup() function duplicates a string into a dynamically allocated buffer. Be aware though that you now become responsible for releasing that buffer (via free()) when you no longer need it.

Another solution would be to replace char *names[MAX]; with char names[MAX][MAX]; (to pre-allocate all of your buffers) and strcpy() into the next location, but this is probably quite wasteful of memory.

mah
  • 39,056
  • 9
  • 76
  • 93
0

This line

names[i] = name;

is wrong. You need to use memcpy or you just overwrite the last string each time. You also need to allocate room for the strings you're receiving ie if MAX == 10;

char *names[10];

is allocating an array of 10 pointers to strings ie there's no room for strings when allocated.

char names[10][MAX];

This gives you an array of pointers and they can each hold MAX characters. Or you need to malloc them before use ie

names[i] = calloc(1, MAX);
size_t name_len = strlen(name);
assert(name_len < MAX);
memcpy(names[i], name, name_len);
names[i][str_len] = '\0';// Null terminate string
Harry
  • 11,298
  • 1
  • 29
  • 43