I am running a C program in Code :: Blocks in windows XP.
I am getting an error as
"drawing operation is attempeted when there was no current window"
What might cause this and how can I solve it?
My code is as follows:
#include <stdio.h>
#include <conio.h>
static int get_code(void);
// System dependent key codes
enum
{
KEY_ESC = 27,
ARROW_UP = 256 + 72,
ARROW_DOWN = 256 + 80,
ARROW_LEFT = 256 + 75,
ARROW_RIGHT = 256 + 77
};
int main(void)
{
int ch;
puts("Press arrow keys, escape key + enter to exit:");
while (( ch = get_code()) != KEY_ESC )
{
switch (ch)
{
case ARROW_UP:
printf("UP\n");
break;
case ARROW_DOWN:
printf("DOWN\n");
break;
case ARROW_LEFT:
printf("LEFT\n");
break;
case ARROW_RIGHT:
printf("RIGHT\n");
break;
}
}
getchar(); // wait
return 0;
}
static int get_code(void)
{
int ch = getch(); // Error happens here
if (ch == 0 || ch == 224)
ch = 256 + getch();
return ch;
}
the α came from the getche() input, it prompts the user for input and when the user press a key then enter it echos that key on the standard output "screen" and since the arrows are non-printable keys that's what happened you can do something like like this:
switch (ch)
{
case ARROW_UP:
printf("\bUP\n");
break;
case ARROW_DOWN:
printf("\bDOWN\n");
break;
case ARROW_LEFT:
printf("\bLEFT\n");
break;
case ARROW_RIGHT:
printf("\bRIGHT\n");
break;
}
actually conio.h is not standard header file which is not supported in Code :: Blocks
http://en.wikipedia.org/wiki/C_standard_library
getch() definition found only in conio.h so it shows error
try scanf to get user input.
Code::Blocks(MinGW) doesnt have conio.h header file. So you cant use the getch() function.
Related
I am writing a snake game in C using the ncurses library, where the screen updates itself every second. As those who have played the game will know, if the user enters various keys or holds down a key for long, there should be no 'buffered' key presses which get stored. In other words, if I hold down w (the up key) and stdin receives a sequence of 20 ws, and subsequently enter a d (the right key), I expect the snake to immediately move to the right, and ignore the buffered ws.
I am trying to achieve this using the ncurses function getch(), but for some reason I am achieving the undesired effect which I have just described; namely that any long key presses are being stored and processed first, before considering the last key pressed, as this MWE will illustrate:
#include <stdio.h>
#include <unistd.h>
#include <ncurses.h>
int main(){
char c = 'a';
initscr();
cbreak();
noecho();
for(;;){
fflush(stdin);
timeout(500);
c = getch();
sleep(1);
printw("%c", c);
}
return 0;
}
Is there any way I can modify this code so that getch() ignores any buffered text? The fflush() right before doesn't seem to be helping.
First the answer to your immediate question: Even when you read from stdin one character at a time, you normally don't want to miss one. If getch() would just return whatever character was entered last, input routines using getch() would become very unreliable.
Even in a snake game, you DO want to get all the characters entered. Imagine the snake moves to the right and the player wants to do a "u-turn" by hitting down and then immediately left. If your game would only pick up the last character, the snake would go directly to the left and thus kill itself. Quite a frustrating game experience ;)
The solution to your problem is simple: make your game loop poll for input much more often than the snake is moved and maintain a queue of requested direction changes. I've done that in my curses-based snake game.
Here is the relevant code from the game loop:
typedef enum
{
NONE,
LEFT,
DOWN,
RIGHT,
UP
} Dir;
// [...]
ticker_start(10);
while (1)
{
screen_refresh(screen);
ticker_wait();
key = getch();
if (key == 'q' || key == 'Q')
{
// quit game
}
switch (key)
{
case KEY_LEFT:
snake_setDir(snake, LEFT);
break;
case KEY_DOWN:
snake_setDir(snake, DOWN);
break;
case KEY_UP:
snake_setDir(snake, UP);
break;
case KEY_RIGHT:
snake_setDir(snake, RIGHT);
break;
case ' ':
// pause game
break;
}
if (!--nextStep)
{
step = snake_step(snake); // move the snake
// code to check for food, killing, ...
}
if (!--nextFood)
{
// add a new food item
}
}
ticker_stop();
And here is how the snake implements and uses the queue:
struct snake
{
// queue of requested directions:
Dir dir[4];
// more properties
};
void
snake_setDir(Snake *self, Dir dir)
{
int i;
Dir p;
p = self->dir[0];
for (i = 1; i < 4; ++i)
{
if (self->dir[i] == NONE)
{
if (dir != p) self->dir[i] = dir;
break;
}
p = self->dir[i];
}
}
static void dequeueDir(Snake *self)
{
int i;
if (self->dir[1] != NONE)
{
for (i=0; i<3; ++i) self->dir[i] = self->dir[i+1];
self->dir[3] = NONE;
}
}
Step
snake_step(Snake *self)
{
dequeueDir(self);
// [...]
switch (self->dir[0])
{
case LEFT:
--newHead->x;
break;
case DOWN:
++newHead->y;
break;
case RIGHT:
++newHead->x;
break;
case UP:
--newHead->y;
break;
default:
break;
}
// [...]
}
Good luck with your game!
I've done some more research and found out that:
The flushinp() routine throws away any typeahead that has been typed by the user and has not yet been read by the program.
This solved my problem.
Source: https://linux.die.net/man/3/flushinp
the following proposed code shows how to ignore all but the last key entered.
#include <stdio.h>
#include <unistd.h>
#include <ncurses.h>
int main( void )
{
char c = ' ';
char lastKey;
initscr();
cbreak();
noecho();
for(;;)
{
timeout(500);
while( (c = getch()) != EOF )
{
lastKey = c;
}
sleep(1);
if( EOF == c )
{
printw("%c", lastKey);
}
}
return 0;
}
I'm trying to write a short program that puts each word on a new line. The new line can be confirmed by tabulator, space or enter. The end of program is putting "#" in console. I have the problem that when I put "enter" to the console it writes next characters in the same line.
The second idea is to make all of this in a table, so I can put formatted text all together in the end. I can't figure this out either.
#include<stdio.h>
#include <conio.h>
#define STOP '#'
int main()
{
char ch;
while ((ch = (_getch())) != STOP) {
switch (ch) {
case '\n':
printf("\n");
break;
case '\t':
printf("\n");
break;
case ' ':
printf("\n");
break;
default:
putchar(ch);
}
}
printf("\nEND");
_getch();
return 0;
}
Because hitting "enter" issues a carriage return char (\r), not a linefeed one.
I noticed it when the cursor jumped back at the start of the line when I pressed "enter".
Fix your code like this (factorize the case statements too):
#include<stdio.h>
#include <conio.h>
#define STOP '#'
int main()
{
char ch;
while ((ch = (_getch())) != STOP) {
switch (ch) {
case ' ':
case '\t':
case '\r': // what was missing
printf("\n");
break;
default:
putchar(ch);
}
}
printf("\nEND");
_getch();
return 0;
}
You probably get a carriage return ('\r') which is what Return typically generates.
So you need to check for that, too. Your code can be simplified:
int main(void)
{
while((ch = _getch()) != STOP)
{
if(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')
ch = '\n';
putchar(ch);
}
}
Since we're always printing exactly one character per iteration, no need to use multiple printing functions. Also, using printf() to print a single constant character is overkill.
I have a problem with the input for a postfixed notation calculator in C.
My teacher asked me to use scanf("%s",token) to get the input. To stop reading tokens, I check if the value returned by scanf is EOF. It works if I use input redirection when testing, but if I write the expression on the Windows cmd I fall into an endless loop. How can I stop scanf when I simply press enter without entering a string?
Here's the code:
#include <stdio.h>
#include <ctype.h>
#include "stack.h"
int main(){
int a,b,t,stop;
char token[10],c;
do{
stop = scanf("%s",token);
if (stop == EOF){
break;
}
if (isdigit(token[0])){
t = atoi(token);
push(t);
}else{
a = top();
pop();
b = top();
pop();
c = token[0];
switch(c){
case '+': t = a + b;
break;
case '-': t = a - b;
break;
case '*': t = a * b;
break;
case '/': t = a / b;
break;
}
push(t);
}
} while(1);
printf("Result: %d\n",top());
}
The problem is in the if block after the stop variable inizialisation, I think. Sorry for my English, I'm an Italian student, I tried to be as neat as I can.
"How can I stop scanf when I simply press enter without entering a string?"
Using scanf() to read '\n' (Enter) is challenging. fgets() or fgetc() is a better approach. But the following shows how to nearly do it with scanf().
The %s in scanf("%s",token); first consumes leading white-space including '\n'. Code must first detect any potential '\n' before calling scanf("%s",token);.
char ws[2];
// Consume white-space, but not \n
scanf("%*[ \f\r\t\v]"); // Depending on locale, this may not be a complete list
if (1 == scanf("%1[\n]", ws) {
break;
}
stop = scanf("%s",token);
if (stop == EOF){
break;
}
A cleaner way to do this.
int ch;
while (isspace(ch = fgetc(stdin)) && ch != '\n');
if (ch == '\n') {
break;
}
ungetc(ch, stdin);
stop = scanf("%s",token);
if (stop == EOF){
break;
}
Only one more question: to stop the program, I had to type ctrl+z
twice. Can you tell me why?
Usually the C standard input in line buffered text mode is implemented by calling a system specific function which reads a line and returns the number of characters in it (including the newline character); when the number 0 is returned, this is considered EOF. Now, when you enter "3 5 +(crtl+z)(ctrl+z)", the first Ctrl-Z ends the input line and causes the reading function to return 5, but this does not indicate EOF to the standard input functions; only after the second Ctrl-Z ist pressed without intervening input, 0 is returned and recognized as EOF.
I have tried this :
switch(c)
case 13 : {printf("enter pressed");break;}
and this :
switch(c)
case '\n' : {printf("enter pressed");break;}
but It didn't work out
Try to use '\r' instead.
The 'Enter' key represent Carriage Return that is the same as '\r'.
"Enter" represents a new line character in C language.
So you can use its ascii value i.e. 10 for its representation.
Eg :
#include<stdio.h>
Try this code :
int main()
{
char ch = '\n';
printf("ch = %d\n", ch);
}
Later you can use the following code as a test for switching '/n'
int main()
{
char ch = '\n';
switch(ch)
{
case '\n' :
printf("Enter pressed\n");
break;
default :
//code
}
}
This program reads from standard input and writes "enter pressed" whenever a newline occurs in the input:
#include <stdio.h>
int main()
{
int c;
for (;;) {
c = getc(stdin);
switch (c) {
case '\n':
printf("enter pressed\n");
break;
case EOF:
return 0;
}
}
}
I think this is what you are looking for.
You might be missing the trailing \n in your printf-call, causing the message to be buffered for output but maybe not flushed so it appears on the screen.
This question already has answers here:
How to avoid pressing Enter with getchar() for reading a single character only?
(14 answers)
Closed 6 years ago.
I'm writing a C program that prints something on terminal using ncurses. It should stop printing when user press 's' and continue again when press 's'. How can I read a key from input without waiting user to press the key?
I tried getch() and getchar() but they wait until a key is pressed...
Edit
This is my code:
int main(void)
{
initscr(); /* Start curses mode */
refresh(); /* Print it on to the real screen */
int i = 0, j = 0;
int state = 0;
while (1)
{
cbreak();
int c = getch(); /* Wait for user input */
switch (c)
{
case 'q':
endwin();
return 0;
case 'c':
state = 1;
break;
case 's':
state = 0;
break;
default:
state = 1;
break;
}
if(state)
{
move(i, j);
i++;
j++;
printf("a");
refresh();
}
}
nocbreak();
return 0;
}
EDIT 2
This works well. I got 100 points :)
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
int main(void)
{
initscr();
noecho();
cbreak(); // don't interrupt for user input
timeout(500); // wait 500ms for key press
int c = 0; // command: [c|q|s]
int s = 1; // state: 1= print, 0= don't print ;-)
int i = 0, j = 0;
while (c != 'q')
{
int c = getch();
switch (c)
{
case 'q':
endwin();
return 0;
case 'c':
s = 1;
break;
case 's':
s = 0;
break;
default:
break;
}
if (s)
{
move(i, j);
printw("a");
i++;
j++;
}
}
endwin();
nocbreak();
return 0;
}
ncurses has the capability to do this through it's own getch() function. See this page
#include <curses.h>
int main(void) {
initscr();
timeout(-1);
int c = getch();
endwin();
printf ("%d %c\n", c, c);
return 0;
}
Since you're using ncurses, you start by calling cbreak to turn off line buffering. Then you'll call nodelay to tell it not to wait before returning -- getch will always return immediately. When it does, you'll check whether a key was pressed, and if so what key that was (and react appropriately).
There's an answer to this in the comp.lang.c FAQ. See question 19.1, "How can I read a single character from the keyboard without waiting for the RETURN key? How can I stop characters from being echoed on the screen as they're typed?".
It's a bit long to post here.