getchar() problem

Hi everybody.

I’m trying to write a program that will control an radio-controlled car,
through the computer.

I want to send commands from the keyboard, but when I use getchar(),
getchar() waits for the return key to be pressed, I want to issue
commands with out pressing the return.

It has some thing to do with the operating system, that process the
input a line at a time by default. I have read some ware that you can
place the OS i raw mode, is it possible and if so, how do I do that?

Can anybody help me, please?
Ricard Kindfalk.

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an radio-controlled car,
through the computer.

I want to send commands from the keyboard, but when I use getchar(),
getchar() waits for the return key to be pressed, I want to issue
commands with out pressing the return.

It has some thing to do with the operating system, that process the
input a line at a time by default. I have read some ware that you can
place the OS i raw mode, is it possible and if so, how do I do that?

Can anybody help me, please?
Ricard Kindfalk.

Thanks to Markus Loffler, we have a very simple solution. I modified it a
little as the original source was in C++.
just include the joined header file in your source, use the supplied funcs
an enjoy!
Hope it will help you.

Alain.

Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an radio-controlled car,
through the computer.

I want to send commands from the keyboard, but when I use getchar(),
getchar() waits for the return key to be pressed, I want to issue
commands with out pressing the return.

It has some thing to do with the operating system, that process the
input a line at a time by default. I have read some ware that you can
place the OS i raw mode, is it possible and if so, how do I do that?

Can anybody help me, please?
Ricard Kindfalk.

Thanks to Markus Loffler, we have a very simple solution. I modified it a
little as the original source was in C++.
just include the joined header file in your source, use the supplied funcs
an enjoy!
Hope it will help you.

Alain.


Name: conio.h
conio.h Type: application/x-unknown-content-type-CHeaderFile
Encoding: base64

Thanks.
Ricard Kindfalk

I will try that.

Fred.

Kindfalk wrote in message <3A9261ED.E19272A3@sm.luth.se>…

Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an radio-controlled
car,
through the computer.

I want to send commands from the keyboard, but when I use getchar(),
getchar() waits for the return key to be pressed, I want to issue
commands with out pressing the return.

It has some thing to do with the operating system, that process the
input a line at a time by default. I have read some ware that you can
place the OS i raw mode, is it possible and if so, how do I do that?

Can anybody help me, please?
Ricard Kindfalk.

Thanks to Markus Loffler, we have a very simple solution. I modified it a
little as the original source was in C++.
just include the joined header file in your source, use the supplied
funcs
an enjoy!
Hope it will help you.

Alain.


Name: conio.h
conio.h Type: application/x-unknown-content-type-CHeaderFile
Encoding: base64

Thanks.
Ricard Kindfalk

I tried your getch, kbhit and other stuff like that,
none of that works.

RAW, UNRAW, termios, readcond, getch, getche, kbhit,
read, select, man I have no clue where to look for this.

It still waits for me to press
on each statement, how come /dev/ser1
works fine without ,
but that /dev/con1 doesn’t want to work at all !?!?!?

Sincerly,

Fred.

Fred wrote in message <96uibm$557$1@inn.qnx.com>…

I will try that.

Fred.

Kindfalk wrote in message <> 3A9261ED.E19272A3@sm.luth.se> >…
Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an radio-controlled
car,
through the computer.

I want to send commands from the keyboard, but when I use getchar(),
getchar() waits for the return key to be pressed, I want to issue
commands with out pressing the return.

It has some thing to do with the operating system, that process the
input a line at a time by default. I have read some ware that you can
place the OS i raw mode, is it possible and if so, how do I do that?

Can anybody help me, please?
Ricard Kindfalk.

Thanks to Markus Loffler, we have a very simple solution. I modified it
a
little as the original source was in C++.
just include the joined header file in your source, use the supplied
funcs
an enjoy!
Hope it will help you.

Alain.


Name: conio.h
conio.h Type: application/x-unknown-content-type-CHeaderFile
Encoding: base64

Thanks.
Ricard Kindfalk

Fred a écrit :

I tried your getch, kbhit and other stuff like that,
none of that works.

RAW, UNRAW, termios, readcond, getch, getche, kbhit,
read, select, man I have no clue where to look for this.

It still waits for me to press <RETURN
on each statement, how come /dev/ser1
works fine without ,
but that /dev/con1 doesn’t want to work at all !?!?!?

Sincerly,

Fred.

Fred wrote in message <96uibm$557$> 1@inn.qnx.com> >…
I will try that.

Fred.

Kindfalk wrote in message <> 3A9261ED.E19272A3@sm.luth.se> >…
Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an radio-controlled
car,
through the computer.

I want to send commands from the keyboard, but when I use getchar(),
getchar() waits for the return key to be pressed, I want to issue
commands with out pressing the return.

It has some thing to do with the operating system, that process the
input a line at a time by default. I have read some ware that you can
place the OS i raw mode, is it possible and if so, how do I do that?

Can anybody help me, please?
Ricard Kindfalk.

Thanks to Markus Loffler, we have a very simple solution. I modified it
a
little as the original source was in C++.
just include the joined header file in your source, use the supplied
funcs
an enjoy!
Hope it will help you.

Alain.


Name: conio.h
conio.h Type: application/x-unknown-content-type-CHeaderFile
Encoding: base64

Thanks.
Ricard Kindfalk
\

Houps!
I think I didn’t understand what you wanted to do!

I have a source code with the following lines:

#include
#include “conio.h”

int main(int argc, char **argv)
{


puts(“hit a key to continue…”);
getch();


}

and it works well, I just have to hit a single key without having to hit return!

using:

getche();

echoes the ascii code…

putc(getch(), stdout);

also works.

Is it what you want to do?

Alain.

This worked for me… you’ll need a couple of includes… mostly termios.h


bool CAppPC::SetupTerminal()
{
struct termios tattr;
// char *name;

/* Make sure stdin is a terminal. */
if (!isatty (STDIN_FILENO)){
fprintf (stderr, “Not a terminal.\n”);
exit (EXIT_FAILURE);
}

/* Save the terminal attributes so we can restore them later. */
tcgetattr (STDIN_FILENO, &saved_attributes);

/* Set the funny terminal modes. /
tcgetattr (STDIN_FILENO, &tattr);
tattr.c_lflag &= ~(ICANON|ECHO); /
Clear ICANON and ECHO. */
tattr.c_cc[VMIN] = 1;
tattr.c_cc[VTIME] = 0;
tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
return true;
}


After initializing the termial

just loop and :

read (STDIN_FILENO, &chIn, 1);

To reset your attributed on exit

atexit (saved_attributes);

Hope this helps…
O by the way, gdb has a bug that you can not read from stdin while debuging
:slight_smile:

“Alain Bonnefoy” <alain.bonnefoy@icbt.com> wrote in message
news:3A9399B5.37DBE0DA@icbt.com

Fred a écrit :

I tried your getch, kbhit and other stuff like that,
none of that works.

RAW, UNRAW, termios, readcond, getch, getche, kbhit,
read, select, man I have no clue where to look for this.

It still waits for me to press <RETURN
on each statement, how come /dev/ser1
works fine without ,
but that /dev/con1 doesn’t want to work at all !?!?!?

Sincerly,

Fred.

Fred wrote in message <96uibm$557$> 1@inn.qnx.com> >…
I will try that.

Fred.

Kindfalk wrote in message <> 3A9261ED.E19272A3@sm.luth.se> >…
Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an
radio-controlled
car,
through the computer.

I want to send commands from the keyboard, but when I use
getchar(),
getchar() waits for the return key to be pressed, I want to issue
commands with out pressing the return.

It has some thing to do with the operating system, that process
the
input a line at a time by default. I have read some ware that you
can
place the OS i raw mode, is it possible and if so, how do I do
that?

Can anybody help me, please?
Ricard Kindfalk.

Thanks to Markus Loffler, we have a very simple solution. I modified
it
a
little as the original source was in C++.
just include the joined header file in your source, use the supplied
funcs
an enjoy!
Hope it will help you.

Alain.

\

Name: conio.h
conio.h Type: application/x-unknown-content-type-CHeaderFile
Encoding: base64

Thanks.
Ricard Kindfalk




Houps!
I think I didn’t understand what you wanted to do!

I have a source code with the following lines:

#include
#include “conio.h”

int main(int argc, char **argv)
{


puts(“hit a key to continue…”);
getch();


}

and it works well, I just have to hit a single key without having to hit
return!

using:

getche();

echoes the ascii code…

putc(getch(), stdout);

also works.

Is it what you want to do?

Alain.

Fred.

Fred wrote in message <96uibm$557$> 1@inn.qnx.com> >…
I will try that.

Fred.

Kindfalk wrote in message <> 3A9261ED.E19272A3@sm.luth.se> >…
Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an radio-controlled
car,
through the computer.

I want to send commands from the keyboard, but when I use
getchar(),



#include
#include “conio.h”

int main(int argc, char **argv)
{


puts(“hit a key to continue…”);
getch();


}

Explain me this:

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

#include “conio.h”
int main(int argc, char **argv)
{
for(;:wink: {
char c = getch();
printf("[%c|%d]", c );
}

return 0;
}


DOESN’T WORK without

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

#include “conio.h”
int main(int argc, char **argv)
{
printf( “Push a key” );
getch();
return 0;
}

Works without return !?!?!?!?

Fred.

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <pthread.h>
#include <sys/neutrino.h>

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

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>

#include <sys/termio.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/uio.h>

struct termios saved_attributes;

bool SetupTerminal()
{
struct termios tattr;
// char *name;

/* Make sure stdin is a terminal. */
if (!isatty (STDIN_FILENO)){
fprintf (stderr, “Not a terminal.\n”);
exit (EXIT_FAILURE);
}

/* Save the terminal attributes so we can restore them later. */
tcgetattr (STDIN_FILENO, &saved_attributes);

/* Set the funny terminal modes. /
tcgetattr (STDIN_FILENO, &tattr);
tattr.c_lflag &= ~(ICANON|ECHO); /
Clear ICANON and ECHO. */
tattr.c_cc[VMIN] = 1;
tattr.c_cc[VTIME] = 0;
tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
return true;
}

int main()
{
SetupTerminal();

char chIn;

for(;:wink:
{
read (STDIN_FILENO, &chIn, 1);
printf( “[%c|%d]” );
}

// atexit (saved_attributes);

return 0;

}

This doesn’t work at all, neither.

In fact, it does nothing even ,
only CTRL-C works.

Do you have to full working code ?

Fred.

Explain me this:

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
for(;:wink: {
char c = getch();
printf("[%c|%d]", c );
}

return 0;
}


DOESN’T WORK without <return

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
printf( “Push a key” );
getch();
return 0;
}

Works without return !?!?!?!?

Fred.

Perhaps this works:

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

#include “conio.h”

int main(int argc, char **argv)
{
for(;:wink: {
fflush( stdout );
fflush( stdin );
char c = getch();
printf("[%c|%d]", c );
}

return 0;
}

Why shall I flush ?

Fred.

Fred wrote:

Fred.

Fred wrote in message <96uibm$557$> 1@inn.qnx.com> >…
I will try that.

Fred.

Kindfalk wrote in message <> 3A9261ED.E19272A3@sm.luth.se> >…
Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an radio-controlled
car,
through the computer.

I want to send commands from the keyboard, but when I use
getchar(),

#include
#include “conio.h”

int main(int argc, char **argv)
{


puts(“hit a key to continue…”);
getch();


}

Explain me this:

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
for(;:wink: {
char c = getch();
printf("[%c|%d]", c );

Probably not relevant, but your printf is missing an argument. I.e. this
should be:

printf("[%c|%d]", c, some_int_argument);

In your case printf would use whatever is on the stack at that moment
and print a spurious int.

}

return 0;
}

DOESN’T WORK without <return

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
printf( “Push a key” );
getch();
return 0;
}

Works without return !?!?!?!?

Fred.

Rick Lake wrote in message
<3A94D46D.251542E8@SPAM.REDIRECTED.TO.DEV.NULL>…

Fred wrote:

Fred.

Fred wrote in message <96uibm$557$> 1@inn.qnx.com> >…
I will try that.

Fred.

Kindfalk wrote in message <> 3A9261ED.E19272A3@sm.luth.se> >…
Alain Bonnefoy skrev:

Kindfalk a écrit :

Hi everybody.

I’m trying to write a program that will control an
radio-controlled
car,
through the computer.

I want to send commands from the keyboard, but when I use
getchar(),

#include
#include “conio.h”

int main(int argc, char **argv)
{


puts(“hit a key to continue…”);
getch();


}

Explain me this:

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
for(;:wink: {
char c = getch();
printf("[%c|%d]", c );

Probably not relevant, but your printf is missing an argument. I.e. this
should be:

printf("[%c|%d]", c, some_int_argument);

In your case printf would use whatever is on the stack at that moment
and print a spurious int.

Sorry, it’s a typo, it’s

printf("[%c|%d]", c, c );

but with fflush it works ?!?

}

return 0;
}

DOESN’T WORK without <return

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
printf( “Push a key” );
getch();
return 0;
}

Works without return !?!?!?!?

Fred.

Sorry, because of the typo, in printf()
it should be read as follow:

Explain me this:

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

#include “conio.h”
int main(int argc, char **argv)
{
for(;:wink: {
char c = getch();
printf("[%c|%d]", c, c );
}

return 0;
}


DOESN’T WORK without

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

#include “conio.h”
int main(int argc, char **argv)
{
printf( “Push a key” );
getch();
return 0;
}

Works without return !?!?!?!?

Perhaps this works:

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

#include “conio.h”

int main(int argc, char **argv)
{
for(;:wink: {
fflush( stdout );
fflush( stdin );
char c = getch();
printf("[%c|%d]", c, c );
}

return 0;
}

Why shall I flush ?

Fred.

Try putting a “\n” after the string to print. I.e. like so:

printf("[%c|%d]\n", c, c);

Reason being that the newline char implicitly forces a fflush() on
stdout. Another way of forcing an implicit fflush() is when the process
blocks waiting for keyboard input. This is the case when it executes
getch(). If you set your stdout to completely raw and unbuffered output
mode, you will see all output immediately. In the library docs you will
find how to do all of this.

good luck,
rick

Fred wrote:

Sorry, because of the typo, in printf()
it should be read as follow:

Explain me this:

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
for(;:wink: {
char c = getch();
printf("[%c|%d]", c, c );
}

return 0;
}

DOESN’T WORK without <return

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”
int main(int argc, char **argv)
{
printf( “Push a key” );
getch();
return 0;
}

Works without return !?!?!?!?

Perhaps this works:

#include <stdio.h
#include <stdlib.h
#include <string.h

#include “conio.h”

int main(int argc, char **argv)
{
for(;:wink: {
fflush( stdout );
fflush( stdin );
char c = getch();
printf("[%c|%d]", c, c );
}

return 0;
}

Why shall I flush ?

Fred.

Fred <fprog@nowhere.users.sourceforge.net> wrote:

Sorry, it’s a typo, it’s

printf("[%c|%d]", c, c );

but with fflush it works ?!?

Amongst the many postings in this thread lie the answers to both
problems you are experiencing. Maybe restating what others have
already said will make things more clear.

Problem #1 is that you failed to use tcsetattr on your stdin fd to
set it to raw mode. The C example from the docs can be pasted into
a file, and compiles and runs just fine. To convince yourself
put a

putchar(getchar());

between the raw() and unraw() calls in main().

Problem #2 is that stdout is buffered, and by default the buffer won’t
be flushed until a newline is encountered (or the buffer becomes full).
Since you were simply echoing your input, what happened was that even
once the input side was working in raw mode, you didn’t see the output
because of the stdout buffering. You can change the buffering behavior
of stdout by using the setvbuf() function (see the docs), or you can
explicitly call fflush(). When you didn’t loop (exiting the program instead)
your output was echoed immediately since the buffers are flushed as part
of the cleanup done when you cleanly exit a C program. The buffering
implemented in the file stream i/o functions is the key advantage to
using these functions in an application. For fun sometime, try writing
a short program that copies a file byte by byte using read()/write()
calls of 1 byte each, then implement the same program using stream i/o
and getchar()/putchar(). Note the dramatic difference in speed that is
the result of the buffering done by the stream i/o functions. For some
types of application its an easy way of increasing the performance by
several hundred times or more without having to write your own
buffering code.

Hope that helps.

Ok this works for me if I do the following …

  1. Your printf statement
    printf( “[%c|%d]” );
    MINE:
    printf( “[%c|%d]\n”, chIn, chIn );
    I found that the output does not do directly out unless you
  1. Add a \n
    or
  2. write( STDOUT_FILENO, str, strlen( str ) );

Complete Text to my program… works for me… Started with your base
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <pthread.h>
#include <sys/neutrino.h>

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

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>

#include <sys/termio.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/uio.h>

struct termios saved_attributes;

bool SetupTerminal()
{
struct termios tattr;
// char *name;

/* Make sure stdin is a terminal. */
if (!isatty (STDIN_FILENO)){
fprintf (stderr, “Not a terminal.\n”);
exit (EXIT_FAILURE);
}

/* Save the terminal attributes so we can restore them later. */
tcgetattr (STDIN_FILENO, &saved_attributes);

/* Set the funny terminal modes. /
tcgetattr (STDIN_FILENO, &tattr);
tattr.c_lflag &= ~(ICANON|ECHO); /
Clear ICANON and ECHO. */
tattr.c_cc[VMIN] = 1;
tattr.c_cc[VTIME] = 0;
tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
return true;
}

int main(void* argc, void* argv[] )
{
SetupTerminal();

char chIn;

for(;:wink:
{
read (STDIN_FILENO, &chIn, 1);
printf( “[%c|%d]\n”, chIn, chIn );
}

// atexit (saved_attributes);

return 0;

}

“Fred” <fprog@nowhere.users.sourceforge.net> wrote in message
news:971sk9$5oj$1@inn.qnx.com

#include <stdio.h
#include <string.h
#include <unistd.h
#include <stdlib.h
#include <fcntl.h
#include <sys/time.h
#include <pthread.h
#include <sys/neutrino.h

#include <stdio.h
#include <string.h
#include <errno.h

#include <unistd.h
#include <stdlib.h
#include <fcntl.h
#include <sys/time.h

#include <sys/termio.h
#include <sys/stat.h
#include <sys/select.h
#include <sys/ioctl.h
#include <sys/types.h
#include <sys/uio.h

struct termios saved_attributes;

bool SetupTerminal()
{
struct termios tattr;
// char *name;

/* Make sure stdin is a terminal. */
if (!isatty (STDIN_FILENO)){
fprintf (stderr, “Not a terminal.\n”);
exit (EXIT_FAILURE);
}

/* Save the terminal attributes so we can restore them later. */
tcgetattr (STDIN_FILENO, &saved_attributes);

/* Set the funny terminal modes. /
tcgetattr (STDIN_FILENO, &tattr);
tattr.c_lflag &= ~(ICANON|ECHO); /
Clear ICANON and ECHO. */
tattr.c_cc[VMIN] = 1;
tattr.c_cc[VTIME] = 0;
tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
return true;
}

int main()
{
SetupTerminal();

char chIn;

for(;:wink:
{
read (STDIN_FILENO, &chIn, 1);
printf( “[%c|%d]” );
}

// atexit (saved_attributes);

return 0;

}

This doesn’t work at all, neither.

In fact, it does nothing even ,
only CTRL-C works.

Do you have to full working code ?

Fred.