C program stops after first the first recursive call - c

I've tried to use character data type to compare in variable reply if equal to y it will continue calling the function recursion(), however, it did only 1 recursion() call and the program terminated. This only work if I use the int data type, as the variable to compare. Please anyone can let me know why this happen?
#include <stdio.h>
void recursion()
{
char reply;
printf("Continue?:");
reply=getchar();
if(reply=='y')
{
printf("Continued\n");
recursion();
}
}
int main()
{
recursion();
return(0);
}
output:
Laptop1:User1$ ./recur
Continue?:y
Continued
Continue?:Laptop1:User1$

getchar() will read newline character if it is, and it will prevent it from continueing.
Try this:
#include <stdio.h>
int getchar2()
{
int c;
do
{
c = getchar();
} while (c == '\n'); /* ignore newline characters */
return c;
}
void recursion()
{
int reply;
printf("Continue?:");
reply=getchar2();
if(reply=='y')
{
printf("Continued\n");
recursion();
}
}
int main()
{
recursion();
return(0);
}

The problem is that when end-users enter 'y' in the terminal, they press Enter. This inserts another character into the stream - '\n'. That is the character that the next call to getchar() would return, ending the chain of calls due to
if(reply=='y')
condition evaluating to "false".
You can fix the problem in several ways - for example, by using scanf:
if (scanf(" %c", &reply) == 1 && reply == 'y')
// ^
// Note the space above
Adding a space character in front of %c ensures that scanf skips whitespace characters before reading the character into reply variable.

Related

Why does getchar() return more than one character?

While trying different things with getchar I figured out that it usually only safes on character in an variable. Somehow when I use a while loop the behaviour changes and it returns more characters if the input is more than one.
Here is my example code for "normal" behaviour. putchar() return only one character even more are put in:
#include <stdio.h>
main() {
char c;
printf("Type a character in here: ");
c = getchar();
printf("You just typed : ");
putchar(c);
}
Somehow when I want to use it in a while loop the putchar() function returns more than one character if more are put in:
Here is the second part:
#include <stdio.h>
void print_input();
main() {
char c;
printf("Type a character in here: ");
c = getchar();
printf("You just typed : ");
putchar(c);
print_input();
}
void print_input() {
char ch = 'x';
while (ch != '#') {
ch = getchar();
putchar(ch);
}
return;
}
Additional question:
While running this in debugger the behaviour somehow is different than if I try this in runtime. Why is that so?
When you enter multiple chars and hit enter, the program will see that whole input (because it's line buffered). So multiple calls to getchar will return subsequent characters and remove them from the stream:
Try to play with this:
char c;
char d;
printf("Type chars in here: ");
c = getchar();
d = getchar();
printf("C: %c \n", c);
printf("D: %c", d);
This is duplicated with:
How is the "getchar()" function able to take multiple characters as input?
You can read more there.

How to fix - unexpected output using getchar() and do-while

I am trying to make a simple code that will read a char from input and execute "Correct" or "Incorrect input" and run the code again until the correct input is entered. First of all it does not work for capital X. The other issue that I want to fix is that after the incorrect input I have to press enter to get the "Enter x" message, instead of getting in immediately after the incorrect input message.
#include <stdio.h>
int main()
{
do
{
printf("Enter x\n");
if (getchar()=='x'|| getchar()=='X')
{
printf("Entered char is X\n");
return 0;
}
else
{
printf("Input incorrect! Please try again!!!\n");
}
}
while (getchar()!='x' || getchar()!='X');
return 0;
}
You need to store the input in a variable, otherwise you keep asking for input several times in a row, for each getchar call.
For weird historic reasons, getchar actually returns an int, since the value EOF that can be returned from it is an int. So the variable must be int.
And finally, each time the user hits enter, a invisible line feed character \n is appended to the input stream. This character does you no good, so you should discard it with an extra read.
#include <stdio.h>
int main (void)
{
int input;
do
{
printf("Enter x\n");
input = getchar();
getchar(); // extra getchar to chew up line feed from stdin
if (input=='x'|| input=='X')
{
printf("Entered char is X\n");
}
else
{
printf("Input incorrect! Please try again!!!\n");
}
} while (input!='x' && input!='X');
return 0;
}
Please note that the opposite of input=='x'|| input=='X' is input!='x' && input!='X' (De Morgan's laws). "If input is not 'x' and input is not 'X' then loop".
When you hit the ENTER key the newline character \n is placed in input buffer. You need to consume that newline character in order to read the next character.
Also you are reading two time, which is unnecessary in this case. So your code should be like this
#include <stdio.h>
int main()
{
char inp;
do
{
printf("Enter x\n");
inp = getchar();
getchar(); // reading the newline character '\n'
if (inp == 'x'|| inp =='X')
{
printf("Entered char is X\n");
return 0;
}
else
{
printf("Input incorrect! Please try again!!!\n");
}
}
while (inp !='x' || inp !='X');
return 0;
}
p.s There is no need to put condition checking in while loop, since you are returning in if condition. while(true) would work fine. Thanks #bruno for pointing that out.
In your code:
if (getchar()=='x'|| getchar()=='X')
getchar() is called twice.
Instead, you should write it this way:
char c = getchar();
if (c=='x'|| c=='X')
for the second part, if your goal is print the message on a new line, then just simply change your printf to:
printf("\nInput incorrect! Please try again!!!\n");

C program to read characters is supposed to stop at newline, but isn't stopping

I have to develop a program that reads characters from the keyboard and write them on screen. However if the character entered is a lowercase letter than it must be converted to an uppercase letter. The reading finishes´after a line (when we press the ENTER key).
My attempt:
int main(void)
{
char c;
printf("Please enter characters. Press ENTER when you are finished\n");
do
{
scanf(" %c", &c);
if (c<='z' && c>='a')
c= c-32;
printf("%c\n", c);
} while(c!='\n');
return EXIT_SUCCESS;
}
However, the program never ends and I don't how do I do that. I'm also not sure if, even though if I insert like 5 characters and the program prints them, if this is the correct form to program it. A character is a character, a single character, it seems to me that it doesn't make much sense that it reads and prints five characters.
Can someone explain what's wrong?
In while(c!='\n');, '\n' is a special whitespace character which is ignored by scanf and thus you will never read it. To terminate you need to specify a terminating character. For example "stop if user enters character x"
then the terminating condition should be while(c!='x');
char can only get one character. So if you want to end your loop you can use like while (c != '0');
For uppercase letter you can use toupper() function from <ctype.h> Library
explanation of what is wrong with the following code:
int main(void)
{
char c;
printf("Please enter characters. Press ENTER when you are finished\n");
do
{
scanf(" %c", &c);
if (c<='z' && c>='a')
c= c-32;
printf("%c\n", c);
} while(c!='\n');
return EXIT_SUCCESS;
}
missing the statement: #include <stdio.h>
call to scanf() has space before %c which causes white space to be consumed/discarded and space, tab, newline are all white space
calculation of uppercase is not desirable. Much better to simply call toupper() which also requires the statement: #include <ctype.h>
when calling scanf() should always check the returned value (not the parameter value) to assure the operation was successful.
the defined value EXIT_SUCCESS requires the statement: #include <stdlib.h>
There are a lot less problems using getchar() rather than scanf()
it is usually a good idea to have the program pause before exiting so you can look at the results on the terminal
getchar() returns an int, not a char
toupper() expects a int parameter and returns an int
EOF is a int, usually with the value -1
Suggest the following code:
#include <stdio.h> // getchar(), printf(), perror(), EOF
#include <stdlib.h> // exit(), EXIT_SUCCESS, EXIT_FAILURE
#include <ctype.h> // toupper(), isalpha(), isdigit(), ispunct()
int main(void)
{
int ch;
printf("Please enter characters. Press ENTER when you are finished\n");
do
{
ch = getchar();
if( !isalpha( ch )
&& !isdigit( ch )
&& !ispunct( ch )
&& !('\n' == ch ) )
{ // then not a printable char
continue;
}
if( EOF == ch )
{
break;
}
ch = toupper(ch);
printf("%c\n", ch);
} while( '\n' != ch );
return EXIT_SUCCESS;
} // end function: main
Note: it would be a good idea to have the program pause, before exiting, so user can look at the output.

C: Scanning While not EOF Loop Unexpected Results

I know there are many questions on the same topic of scanf until EOF is reached, but here's a particular case I haven't seen. Suppose I want to make a C program where the user enters a single character, and the program prints back the character and the number of times the user has entered a character until they press CTRL+D (EOF)
This is what I have:
#include <stdio.h>
int main(){
char thing;
int i=0;
while(scanf("%c", &thing) != EOF){
printf("time:%d, char:%c\n",i,thing);
i++;
}
return 0;
}
However, the output is not as expected. It's the following:
f
time:0, char:f
time:1, char:
p
time:2, char:p
time:3, char:
m
time:4, char:m
time:5, char:
I'm not too sure why i is being incremented again, and why printf gets executed again. Perhaps I'm missing something.
Try
#include <stdio.h>
int main(){
char thing;
int i=0;
while(scanf("%c", &thing) != EOF){
if (thing!='\n') {
printf("time:%d, char:%c\n",i,thing);
i++;
}
}
return 0;
}
#user2965071
char ch;
scanf("%c",&ch);
With such a snippet one reads any ASCII character from the stream including new line, return, tab, or escape. Thus, inside the loop I would test the symbol read with one of the ctype-functions.
Something like this:
#include <stdio.h>
#include <ctype.h>
int main(){
char thing;
int i=0;
while(1 == scanf("%c", &thing)){
if (isalnum(thing)) {
printf("time:%d, char:%c\n",i,thing);
i++;
}
}
return 0;
}
As for me, I think it's not a good idea to check scanf for returning EOF. I would rather check for the number of good read arguments.

EOF not working as expected (C)

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

Resources