Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading newline from previous input when reading from keyboard with scanf()

Tags:

c

string

char

This was supposed to be very simple, but I'm having trouble to read successive inputs from the keyboard.

Here's the code:

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

int main()
{
    char string[200];
    char character;
    printf ("write something: ");
    scanf ("%s", string);
    printf ("%s", string);
    printf ("\nwrite a character: ");
    scanf ("%c", &character);
    printf ("\nCharacter %c  Correspondent number: %d\n", character, character);

    return 0;
}

What is happening

When I enter a string (e.g.: computer), the program reads the newline ('\n') and puts it in character. Here is how the display looks like:

 write something: computer
 computer
 Character:
    Correspondent number: 10

Moreover, the program does not work for strings with more than one word. How could I overcome these problems?

like image 790
El Cid Avatar asked Apr 27 '15 20:04

El Cid


People also ask

How do I stop scanf from going to the next line?

For a simple solution, you could add a space before the format specifier when you use scanf(), for example: scanf(" %c", &ch); The leading space tells scanf() to skip any whitespace characters (including newline) before reading the next character, resulting in the same behavior as with the other format specifiers.

How do I read a new line in scanf?

We can make scanf() to read a new line by using an extra \n, i.e., scanf(“%d\n”, &x) . In fact scanf(“%d “, &x) also works (Note the extra space). We can add a getchar() after scanf() to read an extra newline.

What happens if we put \n in scanf?

An '\n' - or any whitespace character - in the format string consumes an entire (possibly empty) sequence of whitespace characters in the input.

How do I make scanf ignore Whitespaces?

The secret to getting scanf to perform this way is to put a blank in the format string before the %c format specifier. The blank tells scanf to skip white space and it will actually skip any number of white space characters before reading and storing a character.


2 Answers

First scanf read the entered string and left behind \n in the input buffer. Next call to scanf read that \n and store it to character.
Try this

scanf (" %c", &characte);   
     // ^A space before %c in scanf can skip any number of white space characters. 

Program will not work for strings more than one character because scanf stops reading once find a white space character. You can use fgets instead

 fgets(string, 200, stdin);
like image 53
haccks Avatar answered Oct 23 '22 15:10

haccks


OP's first problem is typically solved by prepending a space to the format. This will consume white-space including the previous line's '\n'.

// scanf("%c", &character);
scanf(" %c", &character);

Moreover, the program does not work for strings with more than one word. How could I overcome these problems?

For the the 2nd issue, let us go for a more precise understanding of "string" and what "%s" does.

A string is a contiguous sequence of characters terminated by and including the first null character. 7.1.1 1

OP is not entering a string even though "I enter a string (e.g.: computer)," is reported. OP is entering a line of text. 8 characters "computer" followed by Enter. There is no "null character" here. Instead 9 char "computer\n".

"%s" in scanf("%s", string); does 3 things:

1) Scan, but not save any leading white-space.

2) Scan and save into string any number of non-white-space.

3) Stop scanning when white-space or EOF reached. That char is but back into stdin. A '\0' is appended to string making that char array a C string.

To read a line including spaces, do not use scanf("%s",.... Consider fgets().

fgets(string, sizeof string, stdin);
// remove potential trailing \r\n as needed
string[strcspn(string, "\n")] = 0;

Mixing scanf() and fgets() is a problem as calls like scanf("%s", string); fgets(...) leave the '\n' in stdin for fgets() to read as a line consisting of only "\n". Recommend instead to read all user input using fgets() (or getline() on *nix system). Then parse the line read.

fgets(string, sizeof string, stdin);
scanf(string, "%c", &character);

If code must user scanf() to read user input including spaces:

scanf("%*[\n]"); // read any number of \n and not save.
// Read up to 199 `char`, none of which are \n
if (scanf("%199[^\n]", string) != 1) Handle_EOF();

Lastly, code should employ error checking and input width limitations. Test the return values of all input functions.

like image 20
chux - Reinstate Monica Avatar answered Oct 23 '22 15:10

chux - Reinstate Monica