-2

I want to insert string to the array until I type "ok". Why I am getting just "ok" and original array at the output?

int main(void)
{
    char b[20];
    char* str[10] = { "1","2" };
    int i = 2;
    while (1) {

        gets(b);
        if (strcmp(b, "ok") == 0) break;
        str[i] = b;
        i++;
    }

    for (int j = 0; j < i; j++)
        printf("%s ", str[j]);
    return 0;
}
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
mai brick
  • 25
  • 6
  • 4
    `char* str[10]` is an array of *pointers*. You are storing a *pointer* to the input buffer. They all point to the *same* buffer. Therefore they all point to the most recent input data. – Weather Vane Aug 30 '19 at 19:29
  • 2
    Please read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – Weather Vane Aug 30 '19 at 19:37
  • 1
    Code like this suggests you need to spend more time understanding C strings and the implications of pointers vs. arrays. It's a conceptual block you *need* to have before you can be effective in C. There's many resources, both video and print, which can help you here. – tadman Aug 30 '19 at 19:45
  • 1
    @tadman - I used to 'love the challenge' of coding strings in C. I know C is a great language and worth learning and there are historical reasons for the way its strings work. Also now that I've had java and c# for so long, I see the truth about c strings - they suck! – FastAl Aug 30 '19 at 20:17
  • 1
    @FastAl C was from an era where 100KB of memory was a luxury, so everything is super simple and a lot of the responsibility falls to the programmer. It's still relevant in some parts of the embedded world, but it's *still* super difficult to get your C code 100% correct. A lot of open-source C projects spend innumerable hours dealing with C string issues, especially the never-ending risk of *buffer overflow bugs*. – tadman Aug 30 '19 at 20:20

4 Answers4

0

They all point to b, which gets overwritten in each iteration.

guest
  • 6,450
  • 30
  • 44
0

You need to allocate a string on each iteration:

int main(void)
{
    char* b;
    char* str[10] = { "1","2" };
    int i = 2;
    while (1) {
        b = malloc(20);
        gets(b);
        if (strcmp(b, "ok") == 0) break;
        str[i] = b;
        i++;
    }

    for (int j = 0; j < i; j++)
        printf("%s ", str[j]);

    // free allocated strings
    while (i > 2)
        free(str[--i]);

    return 0;
}
Nathan Xabedi
  • 1,097
  • 1
  • 11
  • 18
0

You need to make a copy of the input string, then save a pointer to the copy of the input string in your array. Something like:

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

int main(void)
  {
  char b[20];
  char *str[10] = { "1","2" };
  int i = 2;
  char *p;
  size_t lenb;

  for(i = 2 ; i < 10 ; ++i)
    {
    fgets(b, sizeof(b), stdin);

    lenb = strlen(b);

    if(lenb > 0 && *(b+lenb-1) == '\n')
      {
      *(b+lenb-1) = '\0';  /* overwrite the trailing \n */
      lenb = strlen(b);
      }

    if (strcmp(b, "ok") == 0)
      break;

    p = malloc(lenb+1);
    strcpy(p, b);

    str[i] = p;
    }

  for (int j = 0; j < i; j++)
    printf("%s\n", str[j]);

  return 0;
  }
0

You need to create a copy of the string when you assign it:

str[i] = strdup(b);

You also may consider using fgets instead of gets; however, you will need to remove the newline:

size_t size;
fgets(str, 20, stdin);
size = strlen(str);
if(str[size-1] == '\n')
    str[size-1] = '\0';

Also, print a newline at the end of your program, so it won't interfere with the shell:

putchar('\n');

Full code:

int main(void)
{
    char b[20];
    char* str[10] = { "1","2" };
    int i = 2;
    while (1) {
        size_t size;
        fgets(str, 20, stdin);
        size = strlen(str);
        if(str[size-1] == '\n')
             str[size-1] = '\0';
        if (strcmp(b, "ok") == 0)
            break;
        str[i] = strdup(b);
        i++;
    }

    for (int j = 0; j < i; j++)
        printf("%s ", str[j]);
    putchar('\n');
    return 0;
}
S.S. Anne
  • 15,171
  • 8
  • 38
  • 76