2

I am quite new to programming in C and I have a problem that I have been trying to solve the last days, but now I am at a point where I don't know what to do.

I am reading in a string with the function "input" which gets then split into parts everytime there is a white space. The parts are stored in char arrays, which works fine so far. However, when I call the next function "checkInput" in main, the char arrays are empty again. What do I have to change, so that the char arrays are not empty when calling the next function?

When I used scanf instead of fgets, it worked. But why?

Any help would be much appreciated.

void input(char* string1, char* string2, char* string3)                     
{
    char ptr[100];

    printf("Enter String: \n");
    fgets(ptr, 100, stdin);
    printf("%s \n", ptr);

    if(ptr != NULL)
    {
        string1 = strtok(ptr, " \n");
        printf("string1: %s \n", string1);
    }
    if(ptr != NULL)
    {
        string2 = strtok(NULL, " \n");
        printf("string2: %s \n", string2);
    }
    if(ptr != NULL)
    {
        string3 = strtok(NULL, " \n \0");
        printf("string3: %s \n", string3);
    }
}

int main(void)
{

    char string1[100];
    char string2[100];
    char string3[100];
    input(string1, string2, string3);
    checkInput(string1, string2, string3);
    return 0;
}

  • Do you mean that I have to pass the char arrays by reference? Like `void input (char** string1, char** string2, char string3**) ` ? – FrüchteTony Feb 08 '20 at 09:26
  • We need the correct definitons of the functions used in `inputCheck()`, like f.e. `IsOperator()`. I found some references but they seem to be meant for C++, not for C. – RobertS supports Monica Cellio Feb 08 '20 at 09:30
  • @FrüchteTony If you want to "ping" a user who is not the OP, you need to set `@username` in front of your comment. – RobertS supports Monica Cellio Feb 08 '20 at 09:42
  • @Yunnosch What parameters are wrong especially? – RobertS supports Monica Cellio Feb 08 '20 at 09:43
  • What happens to `char ptr[100];` when `input()` returns? (hint: `ptr` is part of the `input()` function's function-stack which is destroyed (released for re-use) on return). Since `strtok` will be returning an address within `ptr` to the start of each token -- your strings will point to memory that is no longer valid after the function returns. If you used `scanf ("%99[^\n]", ptr);` instead of `fgets(ptr, 100, stdin);` and you say *"it works"* -- welcome to the world of *Undefined Behavior*... – David C. Rankin Feb 08 '20 at 09:48
  • Additionally, in `main()`, you declare `char string1[100];`, then in `input()` you attempt to assign the pointer from `strtok` to a **copy of** the pointer from `main()`, e,g `string1 = strtok(ptr, " \n");`. This won' work. The copy of the pointers from `main()` already point to valid storage, so you could do, e.g, `ptr = strtok(ptr, " \n"); if (ptr != NULL) strcpy (string1, ptr);` and copy the token to the storage already declared in `main()`. – David C. Rankin Feb 08 '20 at 09:58
  • *When I used scanf instead of fgets, it worked.* - You mean `scanf("%100s",ptr);` instead of `fgest(ptr,100,stdin);`? - By the way you should do it rather `99` instead of `100` characters to save the storage place for the terminating `\0`. – RobertS supports Monica Cellio Feb 08 '20 at 10:03
  • Sorry, I wasn't specific enough about the scanf function. I didn't use ptr with it. I wrote the strings directly into string1, string2 and string3. – FrüchteTony Feb 08 '20 at 10:08
  • However, it is working now. I changed it like David C. Rankin suggested and it works perfectly. – FrüchteTony Feb 08 '20 at 10:09
  • Thank you all very much for your help! This problem was really giving me headache. – FrüchteTony Feb 08 '20 at 10:10

1 Answers1

1

Since you declare string1, string2, string3 in main() as arrays of 100 characters each with automatic storage duration, the storage is already provided for the arrays in input(). The easiest thing to do to get the strings back in main() and avoid the problem with storage for ptr in input() becoming invalid on return is simply to strcpy the tokens to your strings in input(), e.g.

void input(char* string1, char* string2, char* string3)                     
{
    char ptr[100], *p = ptr;

    printf ("Enter String: \n");
    fgets (p, 100, stdin);
    printf("%s \n", ptr);

    if (p != NULL)
    {
        p = strtok (p, " \n");
        if (p)
            strcpy (string1, p);
        printf("string1: %s \n", string1);
    }
    if (p != NULL)
    {
        p = strtok (NULL, " \n");
        if (p)
            strcpy (string2, p);
        printf("string2: %s \n", string2);
    }
    if (p != NULL)
    {
        p = strtok (NULL, " \n \0");
        if (p)
            strcpy (string3, p);
        printf("string3: %s \n", string3);
    }
}

Now string1, string2 and string3 will remain valid until you exit main() and your program is over.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85