1

When a scanf("%s",s); (one of many ways to get a string which is not perfect) encounters a space in the input, it will try to put it in another variable, right? But what hapens if there is only one variable provided as in this case?

Also what other ways are used to input a string? which is the esiest or best one to use and which one does not give problems like the gets(s); function?

Here is my s_insert function now:

// pointer to pointer needed when you allocate memory in the function
void s_insert(char **string_one){   //inserts string (loss of original data)
    *string_one=(char*)malloc(200);
    fgets (*string_one,200,stdin);
} 
VolAnd
  • 6,367
  • 3
  • 25
  • 43
BRHSM
  • 854
  • 3
  • 13
  • 48
  • your current implementation of the function doesn't work **and** it also leaks memory. – The Paramagnetic Croissant Feb 19 '15 at 08:58
  • @TheParamagneticCroissant what do you mean lacking memory? and why does it not work this way? – BRHSM Feb 19 '15 at 09:01
  • When you change the question try to add new piece of information after EDIT subtitle without changing original text of question (it is just advice for future) – VolAnd Feb 19 '15 at 09:05
  • Look example at http://www.cplusplus.com/reference/cstdlib/malloc/ to see how to ensure that memory for string was allocated successfully. – VolAnd Feb 19 '15 at 09:10
  • how should i call the new function? I used `s_insert(string);` before but that does not work any more! – BRHSM Feb 19 '15 at 09:12
  • @CoderGuy it's not "lacking memory". it's **leaking** memory. and it's leaking memory because the modification of a local variable isn't reflected outside the function. But I see you now corrected your code so that it takes a pointer-to-pointer (so now it should work). – The Paramagnetic Croissant Feb 19 '15 at 09:13
  • if your `s` string is defined outside the function as `char *s` use the call `s_insert(&s);` (in this way you sent address of memory where pointer is stored, so function will be able to change pointer) – VolAnd Feb 19 '15 at 09:17
  • I found the problem why it didn't work, it was reading a `\n` from an earlier `scanf();` – BRHSM Feb 19 '15 at 09:18
  • @CoderGuy: To clean everything from an earlier scanf try `fflush(stdin)` before next `scanf` – VolAnd Feb 19 '15 at 09:20
  • and you should know feature of `fgets` (and `gets`) - they read `'\n'` to the destination string, so probably you wish to find this `'\n'` and change to `'\0'`... use `ptr = strchr(s,'\n');` to find newline character (see http://www.cplusplus.com/reference/cstring/strchr/) and than `if(ptr) ptr = '\0'` (of course `char *ptr;` should be defined) – VolAnd Feb 19 '15 at 09:22
  • I used a getchat() afterward so it just gets rid of it that way – BRHSM Feb 19 '15 at 09:29
  • @VolAnd, fflush(stdin) is specifically, in the standard, to be undefined behaviour. fflush() is only for output streams. much better to implement a short loop that uses getchar() where/when the returned value is '\n' or EOF then break out of the loop – user3629249 Feb 19 '15 at 22:09
  • Yes, `fflush()` not always works with `stdin`... http://stackoverflow.com/questions/28382962/wait-for-press-enter-in-c-inside-a-while-loop/28393414#28393414 – VolAnd Feb 20 '15 at 12:14

2 Answers2

2

scanf for %s data specification reads characters before first space symbol (' ', '\n' or '\t'). If you want to read string with spaces (more than two words) use fgets function, that is more safe than 'gets' because you can set the maximum number of character that can be allocated in your memory and avoid segmentation fault.

VolAnd
  • 6,367
  • 3
  • 25
  • 43
  • I know what it does, i just want to know what happends to the rest of the input like when i input `hello world` what happends to `world` <-- note the space. also what are other ways to get a string from a user? please complete the answer – BRHSM Feb 19 '15 at 08:24
  • @CoderGuy it remains in the input stream. – WhozCraig Feb 19 '15 at 08:25
  • ... and can be read by next `scanf` (or killed by `fflush(stdin)` ) – VolAnd Feb 19 '15 at 08:26
  • how does that influence my program, does it stay there till I ask another input, does it get overwritten? – BRHSM Feb 19 '15 at 08:28
  • how do I use the `fgets()` function? – BRHSM Feb 19 '15 at 08:33
  • for string defines as `char s[20];` use `fgets (s , 20 , stdin)` or `if ( fgets (s , 20 , stdin) != NULL ) // process the string s` – VolAnd Feb 19 '15 at 08:36
  • and what if I use `char *s;` and `s=malloc(sizeof(char)*20);`? – BRHSM Feb 19 '15 at 08:39
  • the same `fgets (s , 20 , stdin)` - 20 is the most important (the second parameter cannot be greater then 20 in your case) – VolAnd Feb 19 '15 at 08:40
  • see example in the references http://www.cplusplus.com/reference/cstdio/fgets/ the only difference is that you read not from file but from `stdin` that already openned and shouldn't be closed :-) – VolAnd Feb 19 '15 at 08:42
  • for some reason it does not work, it just looks like it skipes over the statement even though i dont get errors/warnings – BRHSM Feb 19 '15 at 08:46
  • I changed pointer declaration in your question :-) When you sent pointer to function you can change data, but if you need change pointer (e.g. allocate memory with malloc) ypou need pointer to pointer and calling like `s_insert(&s)` – VolAnd Feb 19 '15 at 09:01
  • And checking of malloc result would be useful - see http://www.cplusplus.com/reference/cstdlib/malloc/ – VolAnd Feb 19 '15 at 09:07
2

No, it will only try to "put in a variable" when it encounters a % with a suitable conversion specifier in the first argument. That argument is what controls its behavior, not the input.

Having a single %s and multiple words in the input will simply leave the remaining words still in the input buffer, since scanf() will stop when it's done with the single %s, it has nothing more to do then.

It reads its conversion specification string and tries to read input to match that, not the other way around.

unwind
  • 391,730
  • 64
  • 469
  • 606