How to get newline from scanf, even if this is the only input

I am doing homework that asks me to read an integer n representing the size of the loop, and then read the character string n times and print it right after user input. So I used scanf and then printed it with printf . The problem is that if user input is just a newline, it should print another \n , but scanf seems to ignore input when it is single \n .

Is there a way to do this assignment with scanf or do I need to try something else?

 int i; scanf("%d", &i); for(int ct=0; ct<i; ct++) { char buff[28]; scanf("%s", buff); // if I just press enter here prtinf("%s\n", buff); // then I must get \n\n here } 
+6
source share
3 answers

Using fgets to read in a line is simpler and more reliable:

 if (!fgets(buff, 28, stdin)) { // reading failed, do appropriate error handling // we're just exiting here exit(EXIT_FAILURE); } // We have successfully read in a line, or at least the first 27 // characters of the line. Check whether a full line was read, // if it was, whether the line was empty size_t l = strlen(buff); // <string.h> must be included if (buff[l-1] == '\n') { // a full line was read, remove trailing newline unless // the line was empty if (l > 1) { buff[l-1] = 0; } } else { // the input was too long, what now? // leave the remaining input for the next iteration or // empty the input buffer? } printf("%s\n",buff); 

It does not work with scanf("%s",buff) because most scanf conversions ignore leading white space:

Entering space characters (as indicated by the isspace function) is skipped if the specification includes the [ , c or n specifier.

So, if the user enters an empty string, scanf ignores this entry if its format is not one of the exceptional ones.

Instead, you can use scanf with a character set format,

 scanf("%27[^\n]%*c", buff); 

to read all characters to a new line (but limited to 28 - 1 here to avoid buffer overflow), and then consume a new line without saving it ( * in the conversion specifier %*c suppresses the purpose), which processes non-empty lines consisting entirely of spaces , conversion %s will not. But if the first character of the input is a new line, the conversion %27[^\n] not performed (thanks chux , to draw attention to this), the new line remains in the input buffer and subsequent checks with this format will also fail if the new line does not will be removed from the input buffer.

A somewhat stable (but not ugly and not having too long input) loop using scanf , as far as I can see, should check for a new line before scanning, for example

 for(int ct = 0; ct < i; ++ct) { int ch = getchar(); if (ch == EOF) { // something bad happened; we quit exit(EXIT_FAILURE); } if (ch == '\n') { // we had an empty line printf("\n\n"); } else { // The first character was not a newline, scanning // with the character set format would have succeeded. // But we don't know what comes next, so we put the // character back first. // Although one character of pushback is guaranteed, if (ungetc(ch,stdin) == EOF) { // pushback failed exit(EXIT_FAILURE); } scanf("%27[^\n]%*c",buff); printf("%s\n",buff); } } 

Use fgets , really. This is better.

+12
source

I have two solutions for this:

  • Use fgets instead of scanf .
  • Add \n at the end of the line because you know that use will complete the input with \n .

First decision:

 ... char buf[28]; fgets(buf, 28, stdin); ... 

The second solution:

 #include <string.h> ... char buf[28]; scanf("%s", buf); strcat(buf, "\n"); // add the newline to the string ... 
+2
source

One option is to read one line at a time using gets , and then parse each line using sscanf .

Comment-based EDIT: using fgets more appropriate since you can avoid buffer overflows.

0
source

All Articles