I'm prompting the user to enter the length of an array, initializing a char[] array with this input, and then prompting the user to type a message to enter into the char[] array.
I'm reading the first character of the user's message with getchar().
However, getchar() is reading the new-line escape '\n' before it is reading any user input. It seems to be getting '\n' from the previous printf statement that prompts the user...
Here is the relevant code:
#include <stdio.h>
int main(void) {
int len = 0,
originalLen = 0;
printf("\n\nWhat is the length of the array? ");
scanf("%d", &originalLen);
char str[originalLen]; // intitializing the array
printf("Enter a message to enter into the array: ");
char target = getchar();
str[len] = target;
// why is getchar() reading '\n'?
if (target == '\n') {
printf("\n...what happened?\n");
}
return 0;
} // end of main
It's because the previous scanf does not read the newline after the number.
This can be solved two ways:
Use e.g. getchar to read it
Add a space after the scanf format (e.g. scanf("%d ", ...))
You can use getchar in a loop to flush out stdin before reading the next character.
while((target = getchar()) != '\n' && target != EOF)
When you enter the number and hit the ENTER key, a number and a character are placed in the input buffer, they are namely:
The entered number and
The newline character(\n).
The number gets consumed by the scanf but the newline remains in the input buffer, which is read by getchar().
You need to consume the \n before calling getchar() by using:
scanf("%d ", &originalLen);
^^^
This tells scanf to read the number and an additional character, which is \n.
Related
I am trying to take in user input with spaces and store it in an array of characters.
After, I want to take in a single character value and store it as a char.
However, when I run my code, the prompt for the character gets ignored and a space is populated instead. How can I take in an array of chars and still be allowed to prompt for a single character after?
void main()
{
char userIn[30];
char findChar;
printf("Please enter a string: ");
scanf("%[^\n]s", userIn);
printf("Please enter a character to search for: ");
scanf("%c", &findChar);
//this was put here to see why my single char wasnt working in a function I had
printf("%c", findChar);
}
scanf("%c", &findChar); reads the next character pending in the input stream. This character will be the newline entered by the user that stopped the previous conversion, so findChar will be set to the value '\n', without waiting for any user input and printf will output this newline without any other visible effect.
Modify the call as scanf(" %c", &findChar) to ignore pending white space and get the next character from the user, or more reliably write a loop to read the read and ignore of the input line.
Note also that scanf("%[^\n]s", userIn); is incorrect:
scanf() may store bytes beyond the end of userIn if the user types more than 29 bytes of input.
the s after the ] is a bug, the conversion format for character classes is not a variation of the %s conversion.
Other problems:
void is not a proper type for the return value of the main() function.
the <stdio.h> header is required for this code.
Here is a modified version:
#include <stdio.h>
int main() {
char userIn[30];
int c;
char findChar;
int i, found;
printf("Please enter a string: ");
if (scanf("%29[^\n]", userIn) != 1) {
fprintf(stderr, "Input failure\n");
return 1;
}
/* read and ignore the rest of input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("Please enter a character to search for: ");
if (scanf("%c", &findChar) != 1) {
fprintf(stderr, "Input failure\n");
return 1;
}
printf("Searching for '%c'\n", findChar);
found = 0;
for (i = 0; userIn[i] != '\0'; i++) {
if (userIn[i] == findChar) {
found++;
printf("found '%c' at offset %d\n", c, i);
}
}
if (!found) {
printf("character '%c' not found\n", c);
}
return 0;
}
scanf("%[^\n]s", userIn); is a bit weird. The s is guaranteed not to match, since that character will always be \n. Also, you should use a width modifier to avoid a buffer overflow. Use scanf("%29[^\n]", userIn); That alone will not solve the problem, since the next scanf is going to consume the newline. There are a few options. You could consume the newline in the first scanf with:
scanf("%29[^\n]%*c", userIn);
or discard all whitespace in the next call with
scanf(" %c", &findChar);
The behavior will differ on lines of input that exceed 29 characters in length or when the user attempts to assign whitespace to findChar, so which solution you use will depend on how you want to handle those situations.
I'm trying to use the EOF function but it doesn't work as I expect it. In the debugger mode it doesn't detect the second "scanf" function and just carries on. It keeps on missing out the "scanf" function now and then. Code is posted below
int main() {
char tempString;
int i = 0;
printf("Enter your letter\n");
scanf_s("%c", &tempString);
while (tempString != EOF) {
printf("You entered:%c\n", tempString);
scanf_s("%c", &tempString);
}
}
I have also tried it using the getchar() function but the same thing occurs, code is posted below:
int main() {
char tempString;
int i = 0;
printf("Enter your letter\n");
while ((tempString = getchar()) != EOF) {
printf("You entered:%c\n", tempString);
}
}
Thanks for reading
EDIT:
Firstly you omitted the length argument required by scanf_s for %c and %s formats.
Second, the %c format takes the next character from the input buffer. At the second (and subsequent) entries there was a newline left in the input buffer from the first input. Adding a space before the %c format specifier cleans off that leading whitespace.
Other formats, such as %s and %d do ignore leading whitespace, but not %c.
Thirdly, with scanf the use of EOF is not the way to go, you should control the loop with the return value from scanf which tells you the number of items successfully read.
This program starts by using scanf_s. The second entry ignores the newline after the first entry.
Then it moves to using getchar. In this test the function return value is int, so that's my data type here. That way EOF (-1) won't conflict with any required character data. Note that getchar starts by reading the newline left after the previous scanf_s (which only ignores leading whitespace.
#include <stdio.h>
int main(void)
{
char ch_scanf; // char type
int ch_getchar; // int type
printf("Using scanf_s\n");
if (scanf_s(" %c", &ch_scanf, 1) == 1) { // consumes any leading whitespace
printf("scanf_s value: %d\n", ch_scanf);
}
if (scanf_s(" %c", &ch_scanf, 1) == 1) { // consumes any leading whitespace
printf("scanf_s value: %d\n", ch_scanf);
}
printf("\nUsing getchar\n");
while ((ch_getchar = getchar()) != EOF) {
printf("getchar value: %d\n", ch_getchar);
}
return 0;
}
Sample session:
Using scanf_s
A
scanf_s value: 65
B
scanf_s value: 66
Using getchar
getchar value: 10
C
getchar value: 67
getchar value: 10
^Z
Finally if you want to use the standard library function scanf without MSVC ticking you off, you can do it like this
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
try this
#include <stdio.h>
int main(void) {
char tempString;
printf("Enter your letter\n");
while (scanf_s("%c%*c", &tempString, 1) != EOF) {//%*c for consume newline, 1 is buffer size
printf("You entered:%c\n", tempString);
}
return 0;
}
int tempString;//int for check EOF
printf("Enter your letter\n");
while ((tempString = getchar()) != EOF) {
printf("You entered:%c\n", tempString);
getchar();//consume newline
}
The behaviour of scanf() function in C
Is to read the input from the keyboard buffer till it encounters EOF (ie; till we
press enter key)
In general, it is not advisable to use "%c" in C to read an input character because
The value is collected in keyboard buffer till we hit enter and we could not restrict user entering single character
So, the best way to obtain a character is by using getchar() function.
In the program you have provided you can use any other character to check for end and not EOF since it is used in scanf() implementation to mark the input end.
You may other keys like esc to check for the end
#include <stdio.h>
#include <stdlib.h>
#define esc 27
int main()
{
char ch;
while((ch = getchar()) != esc) {
//print the entered character here
}
}
To know in depth about scanf() implementation look into this scanf() source code
well I have a buffer of I'm assuming 10 characters. I notice when I enter 9 characters though it will skip prompt EX.
Enter a p value:
123456789
Enter a q value:
Enter a k value:
But if I put in 8 or less it will accept it normally as the program is intended, even if the user inputs letters or special characters.
My code:
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>
int main()
{
char pbuffer[10], qbuffer[10], kbuffer[10];
int p=0, q=0, k=0;
int r, i, Q, c, count, sum;
char a[3];
a[0]='y';
while(a[0]=='y' || a[0]=='Y')
{
printf("Enter a p value: \n");
fgets(pbuffer, sizeof(pbuffer), stdin);
p = strtol(pbuffer, (char **)NULL, 10);
printf("Enter a q value: \n");
fgets(qbuffer, sizeof(qbuffer), stdin);
q = strtol(qbuffer, (char **)NULL, 10);
printf("Enter a k value: \n");
fgets(kbuffer, sizeof(kbuffer), stdin);
k = strtol(kbuffer, (char **)NULL, 10);
while(p<q+1)
{
Q=p;
sum=0;
count=0;
while(Q>0)
{
count++;
r = Q%10;
sum = sum + pow(r,k);
Q = Q/10;
}
if ( p == sum && i>1 && count==k )
{
printf("%d\n",p);
}
p++;
a[0]='z';
}
while((a[0]!='y') && (a[0]!='Y') && (a[0]!='n') && (a[0]!='N'))
{
printf("Would you like to run again? (y/n) ");
fgets(a, sizeof(a), stdin);
}
}
return 0;
}
fgets will read in as many characters as it can until it hits either a newline, EOF, or the size of the buffer. It also saves one extra character for a string-terminating \0. So, if you type in 123456789\n and have a 10-character buffer, fgets knows that it can only fit 9 characters in that buffer, so it reads in the first 9 and appends a NULL, giving you 123456789\0 in your buffer, and \n still in STDIN. Then, you call fgets a second time. It doesn't wait for input, because there is already a \n in STDIN, so it reads up to that \n, which happens to be only one character. So, your second buffer is now \n\0, and STDIN is now empty.
Either make your buffers large enough to store the strings that you're going to input, or flush STDIN after every fgets. Likely something like:
while((c = getchar()) != '\n' && c != EOF)
/* Ignore the character */ ;
Add this line after the fgets
scanf("\n");
Instead of reading into a char buffer first, you could use scanf(), e.g. scanf("%d", &p) could replace both fgets() and strtol().
Actually fgets retains the \n character when the size argument provided to it is less than the characters entered. In your case you provided value 10 as size to fgets.
so When you enter 9 characters, it fills the buffer with them and waits for an enter from you to stop reading. And when you press the enter it just puts the null character in the end of it and forward the enter to next prompt and hence skipping it.
check the examples in the answer to a question https://stackoverflow.com/a/11180652/1386897.
Flush the stdin after to the calls to fgets using
int c;
while((c = getchar()) != '\n' && c != EOF);
The reason why fgets dosen't wait for the user to enter data is because fgets knows that the buffer is full (9 chars and one space for \0) and appends a \0 in the end of the string and leaves the \n in the stdin which is taken by the next fgets
Here's a small program:
#include <stdio.h>
int main() {
char str[21], choice[21]; int size;
while(1){
printf("$ ");
fgets(str, 20, stdin);
printf("Entered string: %s", str);
if(str[0] == 'q') {
printf("You sure? (y/n) ");
scanf("%s", choice);
if(choice[0] == 'y' || choice[0] == 'Y')
break;
}
}
return 0;
}
It reads a string using fgets(). If the string starts with a q, it confirms if the user wants to quit, and exits if the user types y.
When I run it and type q, this happens:
$ q
Entered string: q
You sure? (y/n) n
$ Entered string:
$
Note the $ Entered string:. Clearly, fgets() got an empty character or something as input, even though I didn't type anything.
What's going on?
As described in other answer scanf call leaves the newline in the input buffer you can also use getchar() after scanf like this :
scanf("%20s", choice);// always remember( & good) to include field width
// in scanf while reading
Strings otherwise it will overwrite buffer in case of large strings `
getchar(); //this will eat up the newline
Besides , you should also use fgets like this :
fgets(str,sizeof str, stdin); //Its better
It because the scanf call reads a character, but leaves the newline in the buffer. So when you next time call fgets is finds that one newline character and reads it resulting in an empty line being read.
The solution is deceptively simple: Put a space after the format in the scanf call:
scanf("%s ", choice);
/* ^ */
/* | */
/* Note space */
This will cause scanf to read and discard all training whitespace, including newlines.
Use a 'char' of a specific size char choice [1]
OR
char c[1];
c = getchar();
if(c[0] == 'y' || c[1] == 'y'){
// DO SOMETHING
}
I have coded the following codes,but there was a problem
char p[20];
int n;
errno = 0;
n = scanf("%[^\n]",p);
if (1 == n)
{
printf("%s\n",p);
scanf("%[^\n]",p); /*no waiting for input*/
printf("%s\n",p);
}
n = scanf("%[^\n]",p);
This says scan every character except \n ie ENTER key. So it allows you to enter a string and you would have pressed ENTER. This ENTER character is still in stdin buffer which will terminate your next scanf statement
scanf("%[^\n]",p);/*no executed*/
and hence it seems to you that it dint execute! scanf, reads first from the buffer, if it doesn't find sufficient data there, then waits for your input.
Feed the ENTER you entered first to some function like getchar(). ie add a getchar() before your second scanf and now your second scanf will accept input from stdin
Something like
if (1 == n)
{
printf("%s %d\n",p,n);
getchar();
scanf("%[^\n]",p);/*no executed*/
printf("%s\n",p);
}