I'm new to C and I'm currently making a tutorial.
I have decided to combine two exercices and I want to take inputs
as long as I don't just do < return >. This is my code until now:
#include<stdio.h>
char letter;
int i=0;
int main() {
while (i==0) {
printf(">> ");
letter = getchar();
printf("%d\n", letter);
if (letter==10) { //10 is the ASCII id for <return>
printf("End\n");
i = 1;
}
printf("You've entered %c\n", letter);
}
}
The problems is that when I enter a letter for the first time, it does what I want it to do: take a number, and return it on the screen. Directly after that it sets 10 on it's on own!
This is the output:
>> r //I've entered 'r'
114
Das Zeichen ist r
>> 10 //I've entered nothing. It entered that on it's own
End
The letter is
What is going on here? Why does it do that? I didn't enter anything or pressed anything.
The reason that when you enter "r" you also press Enter ('\n' which equals to ASCII 10). The shortest way is to add another getchar() inserted to consume the '\n':
int main() {
while (i==0) {
printf(">> ");
letter = getchar();
getchar();
printf("%d\n", letter);
if (zeichen==10) { //10 is the ASCII id for <return>
printf("End\n");
i = 1;
}
printf("You've entered %c\n", letter);
}
}
There is also another short way which is comparing letter value early after it's assignment like following:
int main() {
while (i==0) {
printf(">> ");
letter = getchar();
if(letter == '\n')
continue;
printf("%d\n", letter);
if (zeichen==10) { //10 is the ASCII id for <return>
printf("End\n");
i = 1;
}
printf("You've entered %c\n", letter);
}
}
however you still need to assign zeichen to something otherwise you'll get undefined behavior
Standard portable C API are not good to handle keystrokes. To "enter r" you need to press "r" "return" so your program using getchar() will receive them both immediately. Your need to use ncurses or cornio.
while (i==0) {
printf(">> ");
letter = getchar();
printf("%d\n", letter);
if (zeichen==10) { //10 is the ASCII id for <return>
printf("End\n");
break;
}
Use break statement instead of i=1;
If using Windows, use _getch() from "conio.h"
Also, instead of checking for 10 (which is the linefeed character not Return), it is better to check for \r, which is what the ENTER key returns. Never use literal values when more descriptive escapes can be used:
line feed = \n
Return = \r
etc.
Related
I was going to make a loop that if I type the alphabet then the ascii value comes out. Unless I type '0' in.
but result is as below. There is the code that I made below the result. Where the value 10 is coming from?
Press any Alphabet
A
65
Press any Alphabet
10
Press any Alphabet
char aski;
while(1)
{
printf("Press any Alphabet\n");
scanf("%c", &aski);
if (aski == '0')
break;
else
printf("%d\n", aski);
}
scanf reads an extra \n. ASCII of \n is 10. That's why you get 10. I suggest you to use getchar() to read extra \n.
#include <stdio.h>
int main()
{
char aski;
while (1)
{
printf("Press any Alphabet\n");
scanf("%c", &aski);
getchar();
if (aski == '0')
break;
else
printf("%d\n", aski);
}
return 0;
}
The output is:
Press any Alphabet
a
97
Press any Alphabet
b
98
PS: I stopped excution after, entering b.
When you are pressing enter you are in fact creating a \n (new line) This char has the value of 10, which is what is being printed.
char c = '\n';
printf("%d",c);
Would give you 10 as result.
Try this
char aski;
scanf("%c ", &aski);
Notice the space after the %c, this makes sure to read all whitespace inputted.
This code is supposed to -
Count the number of characters from input sequence.
Repeat the action until user exits the program.
Use nested do-while loop to achieve this purpose.
But the inner loop is executed only once.
Why?
#include <stdio.h>
int main ()
{
int x;
char i, ans;
i = '\0';
do
{
i = '\0';
x=0;
printf("\nEnter sequence of character:");
do
{
i = getchar();
x++;
}
while(i!='\n');
printf("\nNumber of characters entered is: %d", --x);
printf("\nMore sequences (Y/N) ?");
ans = getchar();
}
while(ans =='Y' || ans == 'y');
After you read the answer yes/no (the line with ans = getchar();), you'll read an "y" and a "\n". You'll consume the "y" and process it, but the next iteration when you read i = getchar();, i will consume the remaining "\n", so will break that do-while loop.
Although it's not my favourite solution, a simple workaround is this:
#include <stdio.h>
int main ()
{
int x;
char i, ans;
i = '\0';
do
{
i = '\0';
x=0;
printf("\nEnter sequence of character:");
do
{
i = getchar();
x++;
}
while(i!='\n');
printf("\nNumber of characters entered is: %d", --x);
printf("\nMore sequences (Y/N) ?");
ans = getchar();
getchar();
}
while(ans =='Y' || ans == 'y');
}
So just consume that extra "\n". This will work only if you type "y" followed by "\n" in terminal. If you type any extra characters, you'll have undefined behaviour.
Note: In your version, try to type: "y1234" then enter when prompted if you want to input again. You'll see that in fact the nested do-while loop works and will count the 4 characters after "y".
What happened:
getchar is a macro that gets a character from stdin.
The delimiter ('\n' in this case) is counted as a separate
character that remains in the buffer and is retrieved the next time
getchar() is called.
This causes inner loop to exit.
What could be done:
Insert the following after ans = getchar();
i = getchar();
if(i != '\n')
ungetc(i,stdin);
New code explained:
ungetc(int x,FILE *stream) pushes a character back into input stream.
stdin is the standard input stream defined in <stdio.h>.
We are reading a character and putting it back if it is not '\n'.
Not exactly sure, but I think that when the user presses enter to finish the 1st input character the input buffer keeps then enter button as the \n character. Try adding if(i == '\n') getChar(); after the x++;.
So my code does the following:
Ask what's the option
If option is 1: Scan some numbers
If option is 2: Print those numbers
After each option, ask if user wanted to continue choosing (Y/N)
This is my main code
while(yesnocheck==1)
{
printf("What's your option?: ");
scanf("%d",&b);
switch(b){
case 1:
printf("How many numbers?: ");
scanf(" %d",&n);
a=(struct sv*)malloc(n*sizeof(struct sv));
for(int i=0;i<n;i++)
scanf("%d",&((a+i)->num));
break;
case 2:
for(int i=0;i<n;i++)
printf("%d\n",(a+i)->num);
break;
}
yesnocheck==yesnochecker();
}
And this is the yesnochecker function:
int yesnochecker()
{
char yesorno;
printf("Do you want to continue? (Y/N)");
while(scanf("%s",&yesorno))
{
if(yesorno=='Y')
return 1;
if(yesorno='N')
return 0;
printf("*Wrong input. Please reenter (Y/N): ");
}
}
So on dev C++, my code won't run correctly. After it's done option 1, when I enter "Y" then choose option 2, case 2 will display some weird numbers. However it works well on online C compilers.
And then, when I change the char yesorno in yesnochecker() function to char yesorno[2] and treat it as a string, the code does work.
Can someone shed some light?
It is a bad idea to read a char c with scanf("%s", &c);. "%s" requires a buffer to store a string. The only string which fits into a char is an empty string (consisting only of a terminator '\0' – not very useful). Every string with 1 character requires 2 chars of storage – 1 for the character, 1 for the terminator ('\0'). Providing a char for storage is Undefined Behavior.
So, the first hint was to use the proper formatter instead – "%c".
This is better as it removes the Undefined Behavior. However, it doesn't solve another problem as the following sample shows:
#include <stdio.h>
int cont()
{
char c; do {
printf("Continue (y/n): ");
scanf("%c", &c);
printf("Input %c\n", c);
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Output:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n):
Input '
'
Continue (y/n): n↵
Input 'n'
Live Demo on ideone
WTH?
The scanf("%c") consumes one character from input. The other character (inserted for the ENTER key) stays in input buffer until next call of any input function.
Too bad, without ENTER it is hard to confirm input on console.
A possible solution is to read characters until the ENTER key is received (or input fails for any reasons). (And, btw., getc() or fgetc() can be used as well to read a single character.):
#include <stdio.h>
int cont()
{
int c;
do {
int d;
printf("Continue (y/n): ");
if ((c = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
printf("Input '%c'\n", c);
for (d = c; d != '\n';) {
if ((d = fgetc(stdin)) < 0) {
fprintf(stderr, "Input failed!\n"); return 0;
}
}
} while (c != 'y' && c != 'n');
return c == 'y';
}
int main()
{
int i = 0;
do {
printf("Loop iteration %d.\n", ++i);
} while (cont());
/* done */
return 0;
}
Output:
Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n): Hello↵
Input 'H'
Continue (y/n): n↵
Input 'n'
Live Demo on ideone
Please, note, that I changed the type for the read character to int. This is because getc()/fgetc() return an int which is capable to store any of the 256 possible char values as well as -1 which is returned in case of failing.
However, it isn't any problem to compare an int with a character constant (e.g. 'y'). In C, the type of character constants is just int (SO: Type of character constant).
This code is for game of craps.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
int roll_dice(void);
bool play_game(void);
int main()
{
int i, ch,win = 0,lose = 0;
bool flag;
srand((unsigned)time(NULL));
do
{
flag = play_game();
if(flag)
{
printf("You win!");
win++;
}
else
{
printf("You lose!");
lose++;
}
printf("\n\nPlay again(Y/N)? ");
scanf("%c", &ch);
ch = getchar();
printf("\n");
}while(ch == 'Y' || ch == 'y');
printf("\nWins: %d Losses: %d",win,lose);
return 0;
}
int roll_dice(void)
{
return rand()%6 + rand()%6 + 2;
}
bool play_game(void)
{
int sum = roll_dice();
printf("You rolled: %d\n", sum);
if(sum == 7 || sum == 11)
return 1;
else if(sum == 2 || sum == 3 || sum == 12)
return 0;
else
{
int point = sum;
printf("Your point is: %d\n", point);
do
{
sum = roll_dice();
printf("You rolled: %d\n", sum);
if(sum == 7)
return 0;
}while(point != sum);
return 1;
}
}
I have problem only with code snippet
printf("\n\nPlay again(Y/N)? ");
scanf("%c", &ch);
ch = getchar();
printf("\n");
I have used, because it terminates after one iteration whatever user input Y or N. I thought I am doing wrong by placing ch = getchar() to eat up \n, I removed it and placed a space before conversion specifier and replaced it by " %c" which also did't work.When I replaced the conversion specifier by %d it works fine.
Is anything going wrong with this?
I visited this post and it is saying same thing I did.
The posted code has undefined behaviour because ch is of type int and the format specifier %c must match a char.
When I replaced the conversion specifier %d it works fine.
When you switch to %d the scanf() fails, because Y or y is not an int, so no input is consumed (apart from leading whitespace which discards the new line character on subsequent iterations of the loop) and the subsequent ch = getchar() actually reads the user entered character, and the code works by fluke. Always check the return value of scanf(), which returns the number of assignments made.
You convert the character with scanf(), and then overwrite it with getchar() immediately afterwards. I wouldn't expect it to work, unless you type "yy" before typing ENTER, but then your second confirmation would fail.
BTW, use the space in " %c".
scanf("%c", &ch);
ch = getchar();
And that's how you lost the previous char stored in ch. How about
ch = fgetc(stdin);
while (fgetc(stdin) != '\n')
;
instead?
printf("Play again? ");
scanf(" %c", &char);
this code works for me. The project is from K.N.King's "C programming : A modern approach" book. I met with this problem before and had the same problem. On page 224 there is a guess.c example project which includes exactly the same command "ask" ("play again"). And author used scanf(" %c", &command); (he used command instead of ch) and it did work. I remember I used it during the "game of craps" project but it did not work. Probably I missed something.
Overall, the expression above 100% does work.
the output should be something like this:
Enter Character : a
Echo : a
I wrote
int c;
while (c != EOF)
{
printf("\n Enter input: ");
c = getchar();
putchar(c);
}
But I get two Enter Input after the echos.
Two characters are retrieved during input. You need to throw away the carriage return.
int c = 0;
int cr;
while (c != EOF)
{
printf("\n Enter input: ");
c = getchar();
cr = getchar(); /* Read and discard the carriage return */
putchar(c);
}
Homework?
If so, I won't give a complete answer/ You've probably got buffered input - the user needs to enter return before anything is handed back to your program. You need to find out how to turn this off.
(this is dependent on the environment of your program - if you could give more details of platform and how you are running the program, we could give better answers)
take fgets eg:
char c[2];
if( fgets( c, 2, stdin ) )
putchar( *c );
else
puts("EOF");
and you dont have any problems with getchar/scanf(%c)/'\n' and so on.
Why don't you use scanf instead?
Example:
char str[50];
printf("\n Enter input: ");
scanf("%[^\n]+", str);
printf(" Echo : %s", str);
return 0;
Outputs
Enter input: xx
Echo : xx
scanf reference
#include <stdio.h>
#include <conio.h>
main(){
int number;
char delimiter;
printf("enter a line of positive integers\n");
scanf("%d%c", &number, &delimiter);
while(delimiter!='\n'){
printf("%d", number);
scanf("%d%c", &number, &delimiter);
}
printf("\n");
getch();
}