1
int main()
{
char inputp1[32], inputp2[32];

char input[32];

printf("-> ");
scanf("%s", input);

strcpy(inputp1, strtok(input , " ,.-"));
strcpy(inputp2, strtok(NULL, " ,.-"));
printf("%s\n", inputp1);
printf("%s\n", inputp2);

}

With this I can enter:

-> 10.10 // my input
10
10

And its the same with 10-10 and 10,10 but using 10 10 does this:

-> 10 10
Segmentation fault: 11

Any ideas?

Note: if this is a dupe just tell me and if it fixes this ill delete this post. Thanks.

John Doe
  • 111
  • 2
  • 14
  • 3
    `scanf` with `%s` reads till a whitespace. – mch May 27 '16 at 19:04
  • 2
    Check the return value of functions that can return null pointers, just in case they _do_ return a null pointer. Then you can avoid your code crashing. – Jonathan Leffler May 27 '16 at 19:16
  • @mch Your comment is incomplete. `"%s"` reads optional leading white-space (ignores them) and _then_ scans non-white-space up to, but not including a subsequent white-space. – chux - Reinstate Monica May 27 '16 at 19:29
  • 1
    See also [How to prevent `scanf()` causing a buffer overflow in C?](https://stackoverflow.com/questions/1621394/how-to-prevent-scanf-causing-a-buffer-overflow-in-c) – Jonathan Leffler May 27 '16 at 21:49

2 Answers2

3

If you want to read till first white space than use scanf("%s", input); this will read character until first space is read.

Use fgets(input, size, stdin) to read entire line.

You can also use something like scanf ("%[^\n]%*c", name); This will read until first newline character and also will flush the newline character so it will not cause any problem. The [] is called scanset. You can read about it here

Despite temptation, you should never use gets() because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

Community
  • 1
  • 1
Deepanshu
  • 488
  • 6
  • 18
  • Yeah scanf() can get an buffer overflow from what I know – John Doe May 27 '16 at 19:27
  • Yes I also don't prefer this `scanf ("%[^\n]%*c", name);` but it is still not deprecated like gets – Deepanshu May 27 '16 at 19:29
  • Okay thanks. Then I can use `if ((strlen(input)>0) && (input[strlen (input) - 1] == '\n')) input[strlen (input) - 1] = '\0';` to remove the newline – John Doe May 27 '16 at 19:30
  • `scanf ("%[^\n]%*c", name);` reads nothing into `name` if the first character is `'\n'`, leaving `name` unchanged and the `'\n'` still in `stdin`. `fgets()` is much better. Also it is not buffer limited. – chux - Reinstate Monica May 27 '16 at 19:31
  • @John Dow `input[strcspn(input, "\n")] = 0;` is a simple 1-liner to remove the potential `'\n'`. Your method is good, yet [no need](http://stackoverflow.com/a/27729970/2410359) to call `strlen()` 3x. – chux - Reinstate Monica May 27 '16 at 19:34
  • 1) using the "%s" format specifier with `scanf()` enables the user to overflow the input buffer. When using '%s" always include a `max length` modifier that is 1 less than the length of the input buffer, so the user cannot overflow the buffer. Overflowing the input buffer results in undefined behaviour and can lead to a seg fault event. 2) always check the returned value (not the parameter value) to assure the operation was successful. I.E. the call to `scanf()` should be: `if ( 1 != scanf( "%31s", input ) { // then handle error due to scanf failing }` – user3629249 May 28 '16 at 19:44
1

scanf("%s", input) reads till first whitespace only. To read the entire line, you can use fgets(input, sizeof(input), stdin) or scanf(" %[^\n]", input);

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Priyansh Goel
  • 2,660
  • 1
  • 13
  • 37