1
#include <stdio.h>

#define MAX_STRING_LENGTH 1024

int main(){ 

char input_name_string[MAX_STRING_LENGTH+1],motive_string[MAX_STRING_LENGTH+1];
printf("What is your name?\n");
scanf("%1024s",input_name_string);
printf("your name is %s \n", input_name_string);
printf("What is your motive?\n");
scanf(" %1024s",motive_string);
printf("your motive is %s \n", motive_string);
return 0; }

So I wrote this simple program for a project in school to try and learn how scanf and printf work. For some reason when this runs it prints the first word in each string on one line then the second word on another line. I don't understand why this is happening? I don't have experience in C but the logic in my code seems correct? Any suggestions

  • 1
    `scanf` should never be used for interactive input. – Kaz Jan 23 '20 at 17:17
  • @kaz what do you mean by interactive input? What specific use case `scanf` solves? – TruthSeeker Jan 23 '20 at 18:08
  • Interactive input is terminal - everything you put from keyboard into your program. Non-interactive would be if it was piped. For example `$ cat .profile | my_processing_prog`. Then you could use scanf() as `cat` standard output is `my_processing_prog` standard input. – tansy Jan 23 '20 at 18:25
  • @TruthSeeker `scanf` is for scanning formatted input prepared for the machine in advance. For instance, formatted data prepared in files, or coming from other programs. Interactive input means from a user interacting with the program. When the input is incorrect, the stream is left in an unexpected state from which it is hard to recover in any user-friendly way. In particular, any excess characters that are not matched by a failing `scanf` stay in the stream and confuse subsequent `scanf` calls. Programs that take user input have to be much more forgiving. – Kaz Jan 23 '20 at 18:33
  • @kaz. Thanks for the information. But I am quite surprised, Why all textbooks and reference books don't mention this! – TruthSeeker Jan 23 '20 at 18:59
  • 1
    @TruthSeeker The K&R2 book says this: *"`scanf` ignores blanks and tabs in its format string. Furthermore, it skips over white space (blanks, tabs, newlines, etc.) as it looks for input values. To read input whose format is not fixed, it is often best to read a line at a time, then pick it apart with `sscanf`."* – Kaz Jan 23 '20 at 20:12

1 Answers1

1

The function scanf with the conversion format specifier used by you reads characters until a white space character is encountered.

Instead use the function fgets.

For example

fgets( input_name_string, sizeof( input_name_string ), stdin );

The function can append also the new line character to the entered string. To remove it you can write

#include <string.h>

/ …

input_name_string[ strcspn( input_name_string, "\n" ) ] = '\0';

As for you format specifier

scanf("%1024s",input_name_string); 

than in any case it is incorrect. Instead of 1024 as the field width should be one less than the size of the character array to reserve one character for the terminating zero character '\0'.

You could write

scanf( "%1023[^\n]\n", input_name_string );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Actually it answers the question "what to do to make it work" and does it right but not why. – tansy Jan 23 '20 at 17:28
  • @tansy Reread one more the answer especially the first statement. – Vlad from Moscow Jan 23 '20 at 17:29
  • I did and still don't see the answer why is ("conceptually") `scanf("%s", "Aaa Bbb");` writing `"Bbb"` into `motive_string` (that's how it looks like from output). – tansy Jan 23 '20 at 17:50
  • @tansy For starters the shown by you call is incorrect and secondly read one more the first statement of my answer. – Vlad from Moscow Jan 23 '20 at 17:51
  • Corrected former comment - what I meant was that input is "Aaa Bbb" and it will "jump" into second printf() and print "Bbb". – tansy Jan 23 '20 at 17:57
  • @tansy You have the third and the ,last attempt to read the first statement of my answer. – Vlad from Moscow Jan 23 '20 at 17:59
  • So, what is the clue? That scanf() reads until white character? It still does not explain why "Bbb" is printed @ `printf(..., motive_string);` – tansy Jan 23 '20 at 18:04
  • @tansy You have an input buffer containing two words separated by a space and two calls of scanf. What will be outputted? – Vlad from Moscow Jan 23 '20 at 18:05
  • Two input buffers and two output buffers. That's why I don't get it. – tansy Jan 23 '20 at 18:08
  • @tansy No, you have only *one* input stream, and *two* buffers as variables. Where, do you think, are two input buffers? – the busybee Jan 23 '20 at 18:11
  • I get it now. I had to made it to write these buffers int files so I could see what's going on on each and every step. I stand corrected. – tansy Jan 23 '20 at 18:19
  • Btw. `scanf( "%1023[^\n]\n", input_name_string );` requires pressing `^D` (Ctrl+d) to indicate end of input. – tansy Jan 23 '20 at 18:27
  • @tansy Neither ^d is required. There are only two calls of scanf. – Vlad from Moscow Jan 23 '20 at 18:31
  • Ok, it will wait for second but it won't show `printf("What is your motive?\n");` until second line is provided. – tansy Jan 23 '20 at 18:39