0

I want to read in two strings with scanf and store them in two variables. How ever only the first one seems to be read properly, the second one just returns (null), but I'm not sure why though.

int main(int argc, char **argv) {
  char *c, *p;

  printf("Enter a command with a parameter: ");
  scanf("%s%s", c, p);
  ...
}

Somebody got an idea, what's going wrong? I don't find any errors and for my understanding it should work.

anonymoose
  • 58
  • 6
  • When I enter `ls -l` it only reads the `ls` properly, that's what i don't understand. `scanf` should read the white space between them and store the `-l` in `p`, but i doesn't. – anonymoose Nov 19 '18 at 15:39
  • 3
    You've not initialized either `c` or `p` to point to anywhere, so you have undefined behaviour. – Jonathan Leffler Nov 19 '18 at 15:42
  • It’s undefined behavior you didn’t initialize the char * variables. – danglingpointer Nov 19 '18 at 15:42
  • You don't look at the return value of `scanf`. How do you know how many fields were parsed? – Gerhardh Nov 19 '18 at 15:50
  • FYI: There's a Q&A [How to prevent `scanf()` causing buffer overflow in C?](https://stackoverflow.com/questions/1621394/how-to-prevent-scanf-causing-a-buffer-overflow-in-c) – Jonathan Leffler Nov 19 '18 at 15:54

3 Answers3

6
char *c, *p;

These are just pointers without any memory behind them. Moreover, they are uninitialized, so reading or assigning they value or reading from or assigning to the memory they point to would be undefined behavior and will spawn nasal demons.

In order to read input from user, you need a place to save the memory to.

char c[20], p[20];

Will allocate 20 characters for c and 20 character for p. c and p are not pointers, but arrays char[20]. However arrays handlers "decay" (read: magically change) into pointers in most contexts.

scanf for "%s" scanf modifier expects a pointer to char char* with enough memory to hold the inputted string.

I would do:

int main(int argc, char **argv) {
  char c[20], p[20];

  printf("Enter a command with a parameter: ");
  scanf("%19s%19s", c, p);
}

The 19 in the %19s limits scanf so that it does not reads input into memory region that is out of bounds in c and/or p pointers, which will lead to undefined behaviour too.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
4

This is undefined behavior. You have not initialized your pointers. Your compiler should tell you about this.

k.c:8:17: warning: variable 'c' is uninitialized when used here [-Wuninitialized]
  scanf("%s%s", c, p);

What you need to do is to initialize your pointers. Using malloc is one way of doing it.

char *c=malloc(SIZE);
char *p=malloc(SIZE);

You want to avoid undefined behavior at ALL COST because it means that the behavior can be ANYTHING, including working the way you want. It can make debugging a nightmare.

But as Swordfish mentioned in the comments, it is suicidal to do this without specifying a max length for your string, because you will have no control over if you write past your buffer, which also is undefined behavior.

klutt
  • 30,332
  • 17
  • 55
  • 95
0

you can also use %ms instead of %s because it allocate memory itself and there is no need of allocation memory manually by programmer.

int main(int argc, char **argv) {
  char *c, *p;

  printf("Enter a command with a parameter: ");
  scanf("%ms%ms", &c, &p); //no need of allocating memory manually
  ... 
}
  • 1
    `"%ms"` is a useful idea with libraries that employ this non-standard enhancement. [difference between %ms and %s scanf](https://stackoverflow.com/q/38685724/2410359). Note that code still should later `free(c), free(p)` – chux - Reinstate Monica Nov 19 '18 at 18:47