0

I am new to C language and working on a small program.

Actually I am trying to take string from the user using scanf. But whenever I enter string with space, program keeps on running infinite and I had to press stop button. I have seen examples online and I have used them as well but that give me a new error then.

Here is my code

struct student s1;
char input[MAX_NAME_SIZE];
printf("Enter name>");
scanf("%s",input);
if(strlen(input) > 10)
{
    int l;
    for(l = 0 ;l <  10;l++)
        s1.name[l] = input[l];
}

int error = 0;
do
{
    if(error == 1)
        printf("Invalid day. ");

    printf("Enter birthday: day>");
    scanf("%u",&s1.birthday.day);
    error = 1;
}while(s1.birthday.day < 1 || s1.birthday.day > 31); //checking the criteria 

I also have used scanf("%[^\n]s,input) but it then skip the scanf and go to the second scanf.

Please help

Adeel Ahmed
  • 67
  • 1
  • 6
  • if its running forever, then its your loop thats the problem. – Takarii May 19 '16 at 13:31
  • And how do you call this? Please specify how to use this to reproduce the issue. What's expected, what's the result. – 4pie0 May 19 '16 at 13:32
  • That's how [`scanf`](http://en.cppreference.com/w/c/io/fscanf) works with the `"%s"` format, it reads *space delimited* "words". If you need to read a whole line, then [there are other alternatives](http://en.cppreference.com/w/c/io/fgets). Also, `scanf` allows you to add options to the format so it won't read to many characters and write out of bounds of your array, no need fot the `strlen` check or manual copying. – Some programmer dude May 19 '16 at 13:32
  • 2
    Can you post the code for `struct student` and what the value of `MAX_NAME_SIZE` is? – BackDoorNoBaby May 19 '16 at 13:33
  • You could use `fgets(input, MAX_NAME_SIZE , stdin);` – LPs May 19 '16 at 13:37
  • It is very unclear what do you want to do and what is happening after you run the program. What is your main func here? What does struct student include? Give us a bit more of the code. – Mirakurun May 19 '16 at 13:37
  • 1
    `scanf("%[^\n]s,input)` --> `scanf(" %[^\n]%*c", input)` – BLUEPIXY May 19 '16 at 13:40
  • Possible duplicate of [string input with spaces](http://stackoverflow.com/questions/18557258/string-input-with-spaces) – wkl Feb 21 '17 at 11:49
  • Possible duplicate of [How do you allow spaces to be entered using scanf?](http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf) – wkl May 18 '17 at 11:40

3 Answers3

2

instead of using

scanf("%s",input);

you can use

gets(input);

It is a function of cstring header file and works same. You may get the problem because scanf accepts only space delimited strings. gets accepts a complete single line, so it may solve your problem.

Hopefully this will work!

EDIT1: Just got it from one of the comments.

use fgets() instead. because gets() doesn't provide buffer overflow protection.

Shubham
  • 41
  • 7
0

The problem, as I hinted about in my first comment, is that scanf only reads space delimited "words".

That means when you give a string with space in it as input, then scanf will read the first part up to the space, and leave the rest of the input in the buffer. Then when you do your input in the loop, scanf will see that it's not a number, and fail to extract the input from the buffer, leaving the input intact, so the next iteration of the loop scanf will attempt to read and parse the exact same input as the last iteration, leading to an infinite loop.

There are also other problems with your code, like you not actually checking if scanf failed or not (follow the link to a scanf (and family) reference and read about what it returns), and not breaking out of the loop if error is set.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

I would never recommend you to use scanf for input which is more than one word. getline() would be the best choice for entering the whole line (etc. Mike Myers 13/04/85) and it's pretty much safe. You also get null terminated string.

You can use this function for example:

char *input(char *output) 
{
    char *Buffer = NULL;
    size_t size = 0;
    int count = 0;

    printf("%s", output);
    count = getline(&Buffer, &size, stdin);
    Buffer[count-1] = '\0';
    return Buffer;
}

In your case it would be best to use it like this:

s1->name=input("Enter the name");
s1->birthday=input("Enter the birthday");

Or you can enter the whole line and use strtok() to parse it.

Mirakurun
  • 4,859
  • 5
  • 16
  • 32