0

I want to store each of the 5 book names in the array and print them out. But what am I doing wrong here ? The output prints out the last entry 5 times.

#include <stdio.h>

int main(int argc, const char * argv[])
{
    char * books[5];
    char currentBook[1024];
    for(int i = 0; i < 5; i++)
    {
        printf("Enter book:\n");
        gets(currentBook);
        books[i] = currentBook;
    }

    for(int i = 0; i <5; i ++)
    {
        printf("Book #%d: %s\n", i, books[i]);
    }
}
alk
  • 69,737
  • 10
  • 105
  • 255
Jenna Maiz
  • 792
  • 4
  • 17
  • 38
  • 1
    Never use `gets`. It's inherently unsafe. – Colonel Thirty Two Apr 30 '16 at 17:00
  • 3
    You are storing the address of `currentBook` in each array element, which contains the most recent entry. I suggest `books[i] = strdup(currentBook);` and then afterwards you must `free` each pointer in the array, because `strdup` obtains memory from `malloc`. – Weather Vane Apr 30 '16 at 17:00

3 Answers3

2

Given your declarations

char * books[5];
char currentBook[1024];

, this code ...

books[i] = currentBook;

... assigns books[i] to be a pointer to the beginning of array currentBook. You do that multiple times for various i, resulting in an array of pointers all pointing to the same array. When you later print the string to which each of those points, it is of course the same string.

You could approach the problem by using strdup() to make a copy of the input buffer instead of assigning each element of books to point to the same thing.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

The problem is,your pointers will be pointing to the same string currentbook. use strdup() instead to duplicate the strings:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char * argv[])
{
    char *books[5];
    char currentBook[1024];
    for (int i = 0; i < 5; i++)
    {
        printf("Enter book:\n");
        fgets(currentBook, sizeof(currentBook), stdin);
        books[i] = strdup(currentBook);
    }

    for (int i = 0; i < 5; i++)
    {
        printf("Book #%d: %s\n", i, books[i]);
        free(books[i]);
    }
}
0

I want to store each of the 5 book names in the array

Then you need to define a suitable array.

Assuming you want to store 5 names, each with a maximum length of 42 characters, you need to define an array of 5 elements each being an array of 42 + 1 characters.

That is define a 2D-array of chars like this

char books [5][42 + 1]; /* Define one more char then you need to store the 
                           `0`-terminator char ending each C "string". */

And use it like this

for(int i = 0; i < 5; i++)
{
  printf("Enter book:\n");
  fgets(books[i], 42 + 1, stdin);
}

On why to not use gets() you might like to read here: Why is the gets function so dangerous that it should not be used?


More on the concept of 0-terminated strings here: https://en.wikipedia.org/wiki/Null-terminated_string

Community
  • 1
  • 1
alk
  • 69,737
  • 10
  • 105
  • 255