MAHAVISHNU G
MAHAVISHNU G

Reputation: 1

What is the use of scanf("\n"); statement before scanf("%[^\n]%*c", s)?

What is the use of scanf("\n"); statement before scanf("%[^\n]%*c", s) ?

int main() 
{
    char ch;
    char str [100];
    char s[100];
    scanf("%c",&ch);
    printf("%c",ch);
    scanf("%s",&str);
    printf("\n%s",str);
    scanf("\n");            // <<< what is the purpose of this line
    scanf("%[^\n]%*c",s);
    printf("\n%s",s);
    return 0;
}

So what is the use of scanf("\n"); statement before scanf("%[^\n]%*c", s) ?

Upvotes: 0

Views: 303

Answers (2)

Steve Summit
Steve Summit

Reputation: 47933

What is the use of scanf("\n");

The true answer is probably that the original author of this code was flailing, desperately trying to get scanf to work, despite scanf's various foibles.

Other evidence that the original author was having problems:

scanf("%c", &ch);

When reading individual characters, the %c often does not work as expected or as desired. Most of the time, at least in code like this, it is necessary to add a space, like this: " %c".

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

This line, also, is difficult to understand. It is attempting to read one full line of text, a task which scanf is not well-suited for.

Overall the code appears to be attempting to read one single character, followed by one string (not containing whitespace), followed by one full line of text (possibly containing whitespace).

Given its shortcomings (and scanf's shortcomings), I'd say it's not even worth trying to figure out what the original code will do. A considerably cleaner way of accomplishing this task (still using scanf) would be

if(scanf(" %c", &ch) != 1) exit(1);
printf("%c\n",ch);
if(scanf("%99s", str) != 1) exit(1);
printf("%s\n", str);
if(scanf(" %99[^\n]", s) != 1) exit(1);
printf("%s\n", s);

Note these changes:

  • checking return value of scanf
  • extra space in " %c", as mentioned
  • %99s instead of plain %s, to avoid array overflow
  • no & before str with %s
  • extra space with %[…] also
  • length modifier 99 with %[…] also
  • no %*c after %[…]
  • (cosmetic/stylistic) printing \n at the end of each line

If you're trying to do anything at all fancy, it's often much easier to just skip scanf, and go with more powerful techniques. I might use something like this:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() 
{
    char chbuf[5];
    char ch;
    char str [100];
    char s[100];

    printf("enter a character:\n");
    if(fgets(chbuf, 5, stdin) == NULL) exit(1);
    ch = *chbuf;
    printf("%c\n", ch);

    printf("enter a string:\n");
    if(fgets(str, 100, stdin) == NULL) exit(1);
    str[strcspn(str, "\n")] = 0;  /* strip \n */
    printf("%s\n", str);

    printf("enter a line:\n");
    if(fgets(s, 100, stdin) == NULL) exit(1);
    s[strcspn(s, "\n")] = 0;
    printf("%s\n", s);
}

This simply used fgets to read all input, one line at a time. To fetch a single character, it then grabs the first character of a short line. (Also it's printing explicit prompts, since that helps to avoid confusion.)

One small drawback of fgets is that it always leaves the \n in the buffer. I've used a common albeit somewhat obscure trick to strip it back off; see this question for an explanation.

This modified program works, although it is different from the original in one significant respect: it will allow whitespace in the first string read as well as the second.

Also, the modified program insists that the three inputs be on three separate lines, while the original would have accepted them all on the same line (or on two lines, or on three lines). Whether that is an improvement or a disimprovement, I can't say. :-)

If you want to limit yourself to a subset of scanf's full complexity, using simple invocations of it for the simple uses it's well-suited for, and avoiding it for the more complicated problems that it's dreadfully painful to use for, you might read the suggestions at this answer.

Upvotes: 4

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

After this incorrect call of scanf

scanf("%s",&str);

where the second parameter shall be

scanf("%s",str);

the input buffer can contain the new line character '\n' and the next call of scanf

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

can read as a result an empty string.

So this call

scanf("\n");

is an attempt to remove the new line character from the input buffer.

However it will be better just to write

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

See the leading space in the format string. It allows to skip white space characters in the input buffer.

Upvotes: 2

Related Questions