0

I have this code.

#include <stdio.h>
struct name
{
    int age;
    char fullname[20];
};

struct name names[20];

int main()
{
    int n,i;
    printf("Count of names:\n");
    scanf("%d",&n);
    for (i = 0; i < n; i++)
    {
        printf("Name %d : ",i);
        scanf("%[^\n]s",names[i].fullname);
    }
    return 0;
}

And when i execute :

rupam@linux ~ $ ./a.out 
Count of names:
5
Name 0 : Name 1 : Name 2 : Name 3 : Name 4 : 
rupam@linux ~ $

It don't wait for user input. Somehow the scanf is not working.

Well, if i use

scanf("%s",names[i].fullname);

It works for single word inputs. What am i doing wrong here ?

13
  • Get rid of the [^\n]. Commented May 5, 2014 at 14:31
  • @BLUEPIXY: Where do you get your spurious s for the format string? Commented May 5, 2014 at 14:37
  • @Deduplicator ah! copy&past. Commented May 5, 2014 at 14:39
  • @BLUEPIXY thanks, adding a space before %[^\n]s worked. Commented May 5, 2014 at 14:39
  • try scanf(" %[^\n]",names[i].fullname); : Because newline remaining(of scanf("%d",&n);,). Commented May 5, 2014 at 14:40

3 Answers 3

2

So lets see what happens with the input here. First, you call scanf("%d" to read an integer. Assuming you enter something like 5Enter, the scanf call will read digits and convert them to an integer. Since it finds at least one digit, it will succeed, reading that digit and leaving the \n from the Enter to be read.

Now you go into the loop, where you call scanf("%[^\n]s" which attempts to read one or more non-newline characters followed by a newline, then attempts to read an s. Since the next character of input is a newline, this immediately fails (reading nothing), but you don't check the return value of scanf, so you don't notice. You then loop attempting to read more, which will fail again.

So what you need to do is ignore the newline. The easiest way is probably to just use a space in the format, which causes scanf to read and ignore whitespace, until it finds a non-whitespace character; change your second scanf to:

scanf(" %19[^\n]", names[i].fullname);

Note some additional changes here. We got rid of the spurious s as you don't particularly want to match an s after the name. We also added a limit of 19 characters to avoid overflowing the fullname array (19 characters max + 1 for the terminating NULL byte).

Sign up to request clarification or add additional context in comments.

Comments

0

Use getchar() after printf in for loop:

#include <stdio.h>
struct name
{
    int age;
    char fullname[20];
};

struct name names[20];

int main()
{
    int n,i;
    printf("Count of names:\n");
    scanf("%d",&n);
    for (i = 0; i < n; i++)
    {
        printf("Name %d : ",i);
        getchar();//getchar here
        scanf("%[^\n]s",names[i].fullname);
    }
    return 0;
}

1 Comment

Seems not as good as just using the scanf option to skip whitespace.
0

If you may work with files with Windows line-ending in the future (redirecting files to stdin), then instead of using one getchar() as suggested by @jahan you can use

if(getchar()=='\r') getchar();

This can increase the portability of your code.

5 Comments

\r\n in a file will be converted to \n in stdin, in Windows. However there is no harm in being more permissive. Ideally keep reading until \n or EOF is hit.
@Matt McNabb After reading this question, I don't think that is necessarily true.
don't think what is true exactly?
@Matt McNabb that \r\n will be converted to \n automatically.
It's implementation-defined, but all Windows compilers that I know of will do that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.