I am trying to detect the Ctrl+D user input, which I know returns EOF. Right now, I know the code waits for input from the stdin stream, but is there a way to let the program continue until the Ctrl+D command is in stdin? The program should continue running past the if statement if Ctrl+D isn't inputted.
char buffer[];
if (fgets(buffer, 10, stdin) == NULL{
//write to file
}
You want to stop your program when the user presses Ctrl+D without actually reading stdin? In this case, you should consider using Ctrl+C instead. But first I will write something about non-blocking I/O, since this is what you are asking for.
There is no way to achieve nonblocking I/O in standard C. However, you could use POSIX-functions like select or fcntl in combination with read. There are other questions about it on StackOverflow which should provide all information you need. This question for example.
If you want to handle Ctrl+C instead, you can use thesignal function:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
volatile bool shouldRun = true;
void sighandler(int) {
shouldRun = false;
}
int main(int argc, char *argv[]) {
if (signal(SIGINT, &sighandler) == SIG_ERR) {
fprintf(stderr, "Could not set signal handler\n");
return EXIT_FAILURE;
}
printf("Program started\n");
while (shouldRun) {
// Do something...
}
printf("Program is shutting down.\n");
return EXIT_SUCCESS;
}
Note that signal handlers (i.e. sighandler) might interrupt your thread at any moment. This means they are prone to race conditions. You must even avoid acquiring any locks within a signal handler. This means just calling printf within a signal handler can cause a deadlock. Just setting boolean flags as shown in the example is fine, though. There are solutions like signal masks and the self pipe trick to circumvent these limitations, but they should not be necessary here.
Since the machine generates EOF on Ctrl+D, you should be checking fgets() for NULL, as fgets() is obliged to return NULL on end of file.
line = fgets(l, BUFFSIZE, stdin)
if (line == NULL)
continue;
On most operating systems, stdin is buffered one line at a time, and any attempt to read it (without going into low-level nasties) will stop until either a line or EOF is available. If you don't mind this, and just want to check for EOF without reading-in any waiting input if EOF is not present, you could use ungetc:
#include <stdio.h>
int check_for_EOF() {
if (feof(stdin)) return 1;
int c = getc(stdin);
if (c == EOF) return 1;
ungetc(c, stdin);
}
int main() {
printf("Start typing:\n");
while (!check_for_EOF()) {
int bytes_typed = 0;
while (getchar() != '\n') bytes_typed++;
printf("You typed a line of %d bytes\n", bytes_typed);
}
printf("You typed EOF\n");
}
You are only guaranteed one character of push-back from ungetc, although most implementations give you much more. And it works only if you're not going to seek the stream later (which is the case with stdin). Notice also that I'm calling it "bytes typed", not "characters typed": Chinese, Japanese and Korean characters for example cannot fit into the char type of most C implementations, and it would depend how the console encodes them when you type (if you have a CJK input method set up or can copy/paste some, you can try it on the above program and see).
It is too much to post here and you are not specific what you have currently and what you want. So here gives you a general idea of how to do it:
Put that if statement inside a forked process or other thread
Send a posix signal to your (parent) process when the key is captured
Add signal handler in your program
If you just wanna terminate the program when C-d is entered, just send a SIGKILL in step 2 and ignore step 3.
If you do not know any term above, Google is your friend
Related
I have a C program with two threads one of those threads is almost all the time blocked in a fgets() waiting for user input. The second thread may need to print to the terminal while the first one is blocked on fgets().
From my tests it seems that the program waits for the fgets() on the first thread to return and then the second thread can print.
Is this who it works or could I print while the the other thread is blocked on the fgets()?
This implementations runs on eCos (embedded Configurable operating system).
Thread locked on fgets():
int my_getline (char** argv, int argvsize)
{
static char line[MAX_LINE];
char *p;
int argc;
fgets(line, MAX_LINE, stdin);
for (argc=0,p=line; (*line != '\0') && (argc < argvsize); p=NULL,argc++) {
p = strtok(p, " \t\n");
argv[argc] = p;
if (p == NULL) return argc;
}
argv[argc] = p;
return argc;
}
Thread trying to print:
while(1){
unsigned char bufr[50];
read_until(bufr);
if (bufr[1] == (unsigned char)NMFL ){
cyg_mutex_lock(&scree_mtx);
printf("Memory half full!\n");
cyg_mutex_unlock(&scree_mtx);
continue;
}
cyg_mbox_put( mbx_serial_userH, bufr );
}
Output (I'm sure the message was there before):
The C standard does not specify any association at all between the standard input stream and the standard output stream. In particular, it does not specify that one thread blocking on reading from standard input, via any standard function, should cause any output function to block.
HOWEVER, the standard also does not say the opposite, that a thread blocking on input input from stdin must not cause another to block on output to stdout. Whether that happens would be a function of the C implementation, and probably of the specific devices with which stdin and stdout are associated.
You appear to be using a Windows C implementation with stdin and stdout both connected to a CMD.EXE window. Windows has a lot of idiosynchrasies, and I'm inclined to guess that the blocking you observe is one of them. I would not expect the same on Linux or OSX, but that does not mean it is erroneous.
#include<stdio.h>
int main(void)
{
int c;
while((c=getchar())!=EOF)
{
if(c==8) // 8 is ASCII value of backspace
printf("\\b");
}
}
Now I want to enter backspace and want getchar() function to return ASCII of backspace to c(int variable)
Note- I am not asking about getch function i know that getch command is able to read backspace
I only want to know whether getchar is able to read backspace or not
If yes,How?
How to do it please explain me
I am new to C programming
If the stream stdin reads from a file, getchar() will handle backspace characters ('\b' or 8 in ASCII) like any other regular character and return it to the caller.
The reason it does not do that when reading from the console (aka terminal or tty) is related to the configuration of the console itself. The console is in cooked mode by default, so as to handle echo, backspace and line buffering, but also signals such as SIGINT sent for Ctrl-C and many more subtile settings.
The C Standard does not provide any way to change the terminal modes, but POSIX systems have the stty command and the termios system calls available to C programs to do this.
Once you configure the console in raw mode, also set stdin to unbuffered mode with setvbuf(stdin, NULL, _IONBF, 0) so getchar() reads each byte from the console as it is typed.
Configuring the console is a complex issue, you may want to read this first: http://www.linusakesson.net/programming/tty/
If your system supports termios as standardized in POSIX.1-2001, then you can manipulate the standard input terminal to not buffer your input. Consider the following example:
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
/* SIGINT handler */
static volatile sig_atomic_t done = 0;
static void handle_done(int signum)
{
if (!done)
done = signum;
}
static int install_done(const int signum)
{
struct sigaction act;
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_handler = handle_done;
act.sa_flags = 0;
if (sigaction(signum, &act, NULL) == -1)
return errno;
return 0;
}
/* Reverting terminal back to original settings */
static struct termios terminal_config;
static void revert_terminal(void)
{
tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminal_config);
}
int main(void)
{
int c;
/* Set up INT (Ctrl+C), TERM, and HUP signal handlers. */
if (install_done(SIGINT) ||
install_done(SIGTERM) ||
install_done(SIGHUP)) {
fprintf(stderr, "Cannot install signal handlers: %s.\n", strerror(errno));
return EXIT_FAILURE;
}
/* Make terminal input noncanonical; not line buffered. Also disable echo. */
if (isatty(STDIN_FILENO)) {
struct termios config;
if (tcgetattr(STDIN_FILENO, &terminal_config) == 0 &&
tcgetattr(STDIN_FILENO, &config) == 0) {
config.c_lflag &= ~(ICANON | ECHO);
config.c_cc[VMIN] = 1; /* Blocking input */
config.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &config);
atexit(revert_terminal);
}
}
/* Set standard input unbuffered. */
setvbuf(stdin, NULL, _IONBF, 0);
printf("Press Ctrl+C to exit.\n");
fflush(stdout);
while (!done) {
c = fgetc(stdin);
if (c == EOF)
printf("Read EOF%s\n", ferror(stdin) ? " as an error occurred" : "");
else
printf("Read %d = 0x%02x\n", c, (unsigned int)c);
fflush(stdout);
}
return EXIT_SUCCESS;
}
The #define line tells your C library headers to expose POSIX.1 features for GNU-based systems.
The done flag is set whenever an INT (Ctrl+C), TERM, or HUP signal is received. (HUP signal is sent if you disconnect from the terminal, for example by closing the terminal window.)
The terminal_config structure will contain the original terminal settings, used by revert_terminal() registered as an at-exit function, to revert the terminal settings back to the original ones read at program startup.
The function isatty(STDIN_FILENO) returns 1 if standard input is a terminal. If so, we obtain the current terminal settings, and modify them for non-canonical mode, and ask that each read blocks until at least one character is read. (The I/O functions tend to get a bit confused if you set .c_cc[VMIN]=0 and .c_cc[VTIME]=0, so that if no input is pending, fgetc() returns 0. Typically it looks like an EOF to stdio.h I/O functions.)
Next, we tell the C library to not internally buffer standard input, using setvbuf(). Normally, the C library uses an input buffer for standard input, for efficiency. However, for us, it would mean the C library would buffer characters typed, and our program might not see them immediately when typed.
Similarly, standard output is also buffered for efficiency. The C library should flush all complete lines to the actual standard output, but we can use the fflush(stdout) call to ensure everything we've written to stdout is flushed to the actual standard output at that point.
In main(), we then have a simple loop, that reads keypresses, and prints them in decimal and hexadecimal.
Note that when a signal is delivered, for example the INT signal because you typed Ctrl+C, the delivery of the signal to our handle_done() signal handler interrupts the fgetc() call if one is pending. This is why you see Read EOF when you press Ctrl+C; if you check ferror(stdin) afterwards, you'll see it returns nonzero (which indicates an error occurred). The "error" in this case is EINTR, "interrupted by a signal".
Also note that when you press some certain keys, like cursor or function keys, you'll see multiple characters generated, usually beginning with 27 and 91 (decimal; 0x1B 0x5B in hexadecimal; "\033[" if expressed as a C string literal). These are usually, but not always, ANSI escape sequences. In general, they are terminal-specific codes that one can obtain via tigetstr(), tigetnum(), and tigetflag() using the terminfo database.
A much more portable way to do this, is to use a Curses library; either ncurses on most systems, or PDCurses on Windows machines. Not only do they provide a much easier interface, but it does it in a terminal-specific way, for maximum compatibility across systems.
C programs using the Curses functions can be compiled against any Curses library, so the same C source file can be compiled and run on Linux, Mac, and Windows machines. However, ncurses does contain quite a few extensions, which may not be provided by other Curses libraries like PDCurses.
I need a command in cmd that works like pause but I can code to continue.
e.g.
system("pause");
some lines of code;`
The problem with system("pause") is that "some lines of code" will not work until the user press sth.
I want to continue cmd with some command.
I want something that run the code but update cmd only when I give the
permission to it.
If I understand correctly, the code shall produce output which you don't want to be shown before you press a key. If you don't mind to have the output paged, you could use something like
FILE *stream = popen("PAUSE<CON&&MORE", "w");
and let the code output to stream (with fprintf(stream, ...) etc.).
Don't ever use system() if you can avoid it. It's crude, error-prone, and non-portable.
C11 introduces threading support, including thrd_sleep(). That should be your preferred solution (if supported by your compiler setup).
If your compiler vendor does not support C11, bugger him about it. That standard is almost four years old now.
WinAPI defines the Sleep() function:
VOID WINAPI Sleep(
_In_ DWORD dwMilliseconds
);
This function causes a thread to relinquish the remainder of its time
slice and become unrunnable for an interval based on the value of
dwMilliseconds.
#include <windows.h>
int main()
{
Sleep( 5000 ); // pause execution for at least 5 seconds
some_lines_of_code;
return 0;
}
I think what you're looking for is a method to check if stdin contains data ready to read; you want to use some non-blocking or asynchronous I/O so that you can read input when it becomes available, and perform other tasks until then.
You won't find a whole heap about non-blocking/asynchronous I/O in standard C, but in POSIX C you can set STDIN_FILENO as non-blocking using fcntl. As an example, here's a program which prompts you to press enter (like pause does) and busy-loops, allowing your code to conduct other (preferably non-blocking) actions inside the loop while it waits for the keystroke (ahemm, byte, since stdin is technically a file):
#include <stdio.h>
#include <fcntl.h>
int main(void) {
char c;
puts("Press any key to continue...");
fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK);
while (read(STDIN_FILENO, 1, &c) != 1 && errno == EAGAIN) {
/* code in here will execute repeatedly until a key is struck or a byte is sent */
errno = 0;
}
if (errno) {
/* code down here will execute when an input error occurs */
}
else {
/* code down here will execute when that precious byte is finally sent */
}
}
That's non-blocking I/O. Other alternatives include using asynchronous I/O or extra threads. You should probably use non-blocking I/O or asynchronous I/O (i.e. epoll or kqueue) for this task in particular; using extra threads just to determine when a character is sent to stdin is likely a little bit too hefty.
I've included an example program using getchar() below, for reference (not that anyone probably needs it), and feel free to address concerns with it if you desire. But my question is:
What exactly is going on when the program calls getchar()?
Here is my understanding (please clarify or correct me):
When getchar is called, it checks the STDIN buffer to see if there is any input.
If there isn't any input, getchar sleeps.
Upon wake, getchar checks to see if there is any input, and if not, puts it self to sleep again.
Steps 2 and 3 repeat until there is input.
Once there is input (which by convention includes an 'EOF' at the end), getchar returns the first character of this input and does something to indicate that the next call to getchar should return the second letter from the same buffer? I'm not really sure what that is.
When there are no more characters left other than EOF, does getchar flush the buffer?
The terms I used are probably not quite correct.
#include <stdio.h>
int getLine(char buffer[], int maxChars);
#define MAX_LINE_LENGTH 80
int main(void){
char line[MAX_LINE_LENGTH];
int errorCode;
errorCode = getLine(line, sizeof(line));
if(errorCode == 1)
printf("Input exceeded maximum line length of %d characters.\n", MAX_LINE_LENGTH);
printf("%s\n", line);
return 0;
}
int getLine(char buffer[], int maxChars){
int c, i = 0;
while((c = getchar()) != EOF && c != '\n' && i < maxChars - 1)
buffer[i++] = c;
buffer[i++] = '\0';
if(i == maxChars)
return 1;
else
return 0;
}
Step 2-4 are slightly off.
If there is no input in the standard I/O buffer, getchar() calls a function to reload the buffer. On a Unix-like system, that normally ends up calling the read() system call, and the read() system call puts the process to sleep until there is input to be processed, or the kernel knows there will be no input to be processed (EOF). When the read returns, the code adjusts the data structures so that getchar() knows how much data is available. You description implies polling; the standard I/O system does not poll for input.
Step 5 uses the adjusted pointers to return the correct values.
There really isn't an EOF character; it is a state, not a character. Even though you type Control-D or Control-Z to indicate 'EOF', that character is not inserted into the input stream. In fact, those characters cause the system to flush any typed characters that are still waiting for 'line editing' operations (like backspace) to change them so that they are made available to the read() system call. If there are no such characters, then read() returns 0 as the number of available characters, which means EOF. Then getchar() returns the value EOF (usually -1 but guaranteed to be negative whereas valid characters are guaranteed to be non-negative (zero or positive)).
So basically, rather than polling, is it that hitting Return causes a certain I/O interrupt, and then when the OS receives this, it wakes up any processes that are sleeping for I/O?
Yes, hitting Return triggers interrupts and the OS kernel processes them and wakes up processes that are waiting for the data. The terminal driver is woken by the kernel when interrupt occurs, and decides what to do with the character(s) that were just received. They may be stashed for further processing (canonical mode) or made available immediately (raw mode), etc. Assuming, of course, that the input is a terminal; if the input is from a disk file, it is simpler in many ways — or if it is a pipe, or …
Nominally, it isn't the terminal app that gets woken by the interrupt; it is the kernel that wakes first, then the shell running in the terminal app that is woken because there's data for it to read, and only when there's output does the terminal app get woken.
I say 'nominally' because there's an outside chance that in fact the terminal app does mediate the I/O via a pty (pseudo-tty), but I think it happens at the kernel level and the terminal application is involved fairly late in the process. There's a huge disconnect really between the keyboard where you type and the display where what you type appears.
See also Canonical vs non-canonical terminal input.
I am confused about getchar()'s role in the following code. I mean I know it's helping me see the output window which will only be closed when I press the Enter key.
So getchar() is basically waiting for me to press enter and then reads a single character.
What is that single character this function is reading? I did not press any key from the keyboard for it to read.
Now when it's not reading anything, why does it not give an error saying "hey, you didn't enter anything for me to read"?
#include <stdio.h>
int main()
{
printf( "blah \n" );
getchar();
return 0;
}
That's because getchar() is a blocking function.
You should read about blocking functions, which basically make the process wait for something to happen.
The implementation of this waiting behavior depends on the function, but usually it's a loop that waits for some event to happen.
For the case of the getchar() function, this probably is implemented as a loop that constantly reads a file (stdin for this case) and checks weather the file is modified. If the file is modified, the loop behaves by doing something else.
The getchar() function will simply wait until it receives a character, holding the program up until it does.
A character is sent when you hit the enter key; under a Windows OS, it will send a carriage return (CR) and a line-feed (LF).
See this CodingHorror post for a nicely put explanation.
(...the explanation of the CR+LF part, not the getchar() blocking part)
Try this:
#include <stdio.h>
int main(int argc, char *argv[])
{
char ch;
printf("I'm now going to block until you press something and then return... ");
ch = getchar();
if (ch >= 0)
printf("\nYou pressed %c\n", ch);
else
printf("\nAliens have taken over standard input! Run!\n");
return 0;
}
getchar() will cause your program to go to sleep until a keyboard (or whatever is attached to stdin) interrupt is received. This means it's blocking, no additional code will execute until getchar() returns.
It's very, very helpful to look at the return value of a function in order to understand it.
Any function may block, unless it provides some mechanism to prevent blocking. For instance, open() allows a O_NONBLOCK flag which is helpful for opening slow to respond devices like modems. In short, if it gets input from a terminal or has to wait to get an answer from the kernel or some device, there's a very good chance it might block.
getchar() blocks your program's execution until a key is pressed. So, there's no error if no key is pressed, getchar() will wait for it to happen :)
You can learn more about how getchar behaves here:
http://www.cppreference.com/wiki/c/io/getchar
...this should answer your question:)
I think what confuses you is that the Enter key is needed befor the program continues. By default, the terminal will buffer all information until Enter is pressed, before even sending it to the C program.
see discussion of Enter problem here